Skip to content

Commit

Permalink
Implement visit_unary operator logic in copiler for minus unary opera… (
Browse files Browse the repository at this point in the history
#46)

* Implement visit_unary operator logic in copiler for minus unary operator.

* Add test for missing unary operator case.

Co-authored-by: Jarosław Konik <[email protected]>
  • Loading branch information
joczkowski and jarkonik authored Dec 4, 2021
1 parent 3ecd494 commit 327f896
Show file tree
Hide file tree
Showing 4 changed files with 62 additions and 4 deletions.
2 changes: 1 addition & 1 deletion examples/mandelbrot.rc
Original file line number Diff line number Diff line change
Expand Up @@ -58,7 +58,7 @@ while y < HEIGHT {
if sqrt(vecget(acc, 0) * vecget(acc, 0) + vecget(acc, 1) * vecget(acc, 1)) > 2 {
isstable = 0
}
if sqrt(vecget(acc, 0) * vecget(acc, 0) + vecget(acc, 1) * vecget(acc, 1)) < 0-2 {
if sqrt(vecget(acc, 0) * vecget(acc, 0) + vecget(acc, 1) * vecget(acc, 1)) < -2 {
isstable = 0
}
i = i + 1
Expand Down
17 changes: 15 additions & 2 deletions src/compiler/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -219,8 +219,21 @@ impl Visitor<Value> for Compiler {
val
}

fn visit_unary(&mut self, _: &expression::Unary) -> Value {
todo!()
fn visit_unary(&mut self, expr: &expression::Unary) -> Value {
match expr.operator {
expression::Operator::Minus => {
let r = match self.walk(&expr.right) {
Value::Numeric(p) => p,
_ => panic!("panic"),
};

Value::Numeric(self.builder.build_fneg(r, ""))
}
_ => panic!(
"operator {:?} is not valid for unary operations",
expr.operator
),
}
}

fn visit_grouping(&mut self, expr: &expression::Expression) -> Value {
Expand Down
4 changes: 4 additions & 0 deletions src/llvm/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -139,6 +139,10 @@ impl Builder {
Value(unsafe { LLVMBuildFMul(self.0, lhs.0, rhs.0, c_str(name).as_ptr()) })
}

pub fn build_fneg(&self, rhs: Value, name: &str) -> Value {
Value(unsafe { LLVMBuildFNeg(self.0, rhs.0, c_str(name).as_ptr()) })
}

pub fn build_fcmp(&self, lhs: Value, rhs: Value, operator: Cmp, name: &str) -> Value {
Value(unsafe {
LLVMBuildFCmp(
Expand Down
43 changes: 42 additions & 1 deletion tests/compiler_tests.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
use rocklang::compiler::{Compile, Compiler};
use rocklang::expression::{
Assignment, Binary, Conditional, Expression, FuncCall, FuncDecl, Operator, While,
Assignment, Binary, Conditional, Expression, FuncCall, FuncDecl, Operator, Unary, While,
};
use rocklang::parser::{Param, Program, Type};

Expand Down Expand Up @@ -693,3 +693,44 @@ fn it_panics_when_not_equal_string_to_numeric() {
Box::new(Expression::Numeric(10.0))
);
}

#[test]
fn it_compiles_unary_operator() {
let program = Program {
body: vec![Expression::Unary(Unary {
operator: Operator::Minus,
right: Box::new(Expression::Numeric(2.0)),
})],
};

let mut compiler = Compiler::new(program);
compiler.compile().unwrap();
}

#[test]
#[should_panic]
fn it_panics_when_pass_string_to_unary() {
let program = Program {
body: vec![Expression::Unary(Unary {
operator: Operator::Minus,
right: Box::new(Expression::String("foo".to_string())),
})],
};

let mut compiler = Compiler::new(program);
compiler.compile().unwrap();
}

#[test]
#[should_panic]
fn it_panics_when_wrong_unary_operator() {
let program = Program {
body: vec![Expression::Unary(Unary {
operator: Operator::Plus,
right: Box::new(Expression::Numeric(2.0)),
})],
};

let mut compiler = Compiler::new(program);
compiler.compile().unwrap();
}

0 comments on commit 327f896

Please sign in to comment.