Prefix unary ops with unary_ in tables
This commit is contained in:
parent
dc50ce64eb
commit
d929f49bc8
5 changed files with 26 additions and 50 deletions
|
@ -32,6 +32,7 @@ pub fn start_compiler() {
|
|||
for instruction in compile(&line) {
|
||||
println!("{instruction}");
|
||||
}
|
||||
println!();
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -13,20 +13,12 @@ pub fn interpret<'source>(ast: &AstNode<'source>, symbols: &mut SymTab<'source,
|
|||
IntLiteral(val) => Value::Int(*val),
|
||||
BoolLiteral(val) => Value::Bool(*val),
|
||||
Identifier(name) => *symbols.get(name),
|
||||
UnaryOp(op, expr) => match *op {
|
||||
"-" => {
|
||||
let Value::Func(op_fn) = symbols.get("neg") else {
|
||||
panic!("Operator {} does not correspond to a function!", op);
|
||||
};
|
||||
op_fn(&[interpret(expr, symbols)])
|
||||
}
|
||||
_ => {
|
||||
let Value::Func(op_fn) = symbols.get(op) else {
|
||||
panic!("Operator {} does not correspond to a function!", op);
|
||||
};
|
||||
op_fn(&[interpret(expr, symbols)])
|
||||
}
|
||||
},
|
||||
UnaryOp(op, expr) => {
|
||||
let Value::Func(op_fn) = symbols.get(&format!("unary_{op}")) else {
|
||||
panic!("Operator {} does not correspond to a function!", op);
|
||||
};
|
||||
op_fn(&[interpret(expr, symbols)])
|
||||
}
|
||||
BinaryOp(left, op, right) => match *op {
|
||||
"and" => {
|
||||
let left_val = interpret(left, symbols);
|
||||
|
|
|
@ -42,8 +42,8 @@ impl IrVar {
|
|||
(IrVar::new("<="), Func(vec![Int, Int], Box::new(Bool))),
|
||||
(IrVar::new(">"), Func(vec![Int, Int], Box::new(Bool))),
|
||||
(IrVar::new(">="), Func(vec![Int, Int], Box::new(Bool))),
|
||||
(IrVar::new("not"), Func(vec![Bool], Box::new(Bool))),
|
||||
(IrVar::new("neg"), Func(vec![Int], Box::new(Int))),
|
||||
(IrVar::new("unary_not"), Func(vec![Bool], Box::new(Bool))),
|
||||
(IrVar::new("unary_-"), Func(vec![Int], Box::new(Int))),
|
||||
(IrVar::new("or"), Func(vec![Bool, Bool], Box::new(Bool))),
|
||||
(IrVar::new("and"), Func(vec![Bool, Bool], Box::new(Bool))),
|
||||
])
|
||||
|
|
|
@ -58,8 +58,8 @@ impl<'source> SymTab<'source, Type> {
|
|||
("<=", Func(vec![Int, Int], Box::new(Bool))),
|
||||
(">", Func(vec![Int, Int], Box::new(Bool))),
|
||||
(">=", Func(vec![Int, Int], Box::new(Bool))),
|
||||
("not", Func(vec![Bool], Box::new(Bool))),
|
||||
("neg", Func(vec![Int], Box::new(Int))),
|
||||
("unary_not", Func(vec![Bool], Box::new(Bool))),
|
||||
("unary_-", Func(vec![Int], Box::new(Int))),
|
||||
("or", Func(vec![Bool, Bool], Box::new(Bool))),
|
||||
("and", Func(vec![Bool, Bool], Box::new(Bool))),
|
||||
]);
|
||||
|
@ -85,8 +85,8 @@ impl<'source> SymTab<'source, Value> {
|
|||
("<=", Func(Value::le)),
|
||||
(">", Func(Value::gt)),
|
||||
(">=", Func(Value::ge)),
|
||||
("not", Func(Value::not)),
|
||||
("neg", Func(Value::neg)),
|
||||
("unary_not", Func(Value::not)),
|
||||
("unary_-", Func(Value::neg)),
|
||||
]);
|
||||
|
||||
SymTab {
|
||||
|
|
|
@ -19,40 +19,23 @@ fn get_type<'source>(ast: &mut AstNode<'source>, symbols: &mut SymTab<'source, T
|
|||
IntLiteral(_) => Type::Int,
|
||||
BoolLiteral(_) => Type::Bool,
|
||||
Identifier(name) => symbols.get(name).clone(),
|
||||
UnaryOp(op, mut expr) => match op {
|
||||
"-" => {
|
||||
let expr_types = vec![type_check(&mut expr, symbols)];
|
||||
UnaryOp(op, mut expr) => {
|
||||
let expr_types = vec![type_check(&mut expr, symbols)];
|
||||
|
||||
let Type::Func(sig_arg_types, sig_ret_type) = symbols.get("neg") else {
|
||||
panic!("Identifier {} does not correspond to an operator!", op);
|
||||
};
|
||||
let Type::Func(sig_arg_types, sig_ret_type) = symbols.get(&format!("unary_{op}"))
|
||||
else {
|
||||
panic!("Identifier {} does not correspond to an operator!", op);
|
||||
};
|
||||
|
||||
if expr_types != *sig_arg_types {
|
||||
panic!(
|
||||
"Operator {} argument types {:?} don't match expected {:?}",
|
||||
op, expr_types, *sig_arg_types
|
||||
);
|
||||
}
|
||||
|
||||
(**sig_ret_type).clone()
|
||||
if expr_types != *sig_arg_types {
|
||||
panic!(
|
||||
"Operator {} argument types {:?} don't match expected {:?}",
|
||||
op, expr_types, *sig_arg_types
|
||||
);
|
||||
}
|
||||
_ => {
|
||||
let expr_types = vec![type_check(&mut expr, symbols)];
|
||||
|
||||
let Type::Func(sig_arg_types, sig_ret_type) = symbols.get(op) else {
|
||||
panic!("Identifier {} does not correspond to an operator!", op);
|
||||
};
|
||||
|
||||
if expr_types != *sig_arg_types {
|
||||
panic!(
|
||||
"Operator {} argument types {:?} don't match expected {:?}",
|
||||
op, expr_types, *sig_arg_types
|
||||
);
|
||||
}
|
||||
|
||||
(**sig_ret_type).clone()
|
||||
}
|
||||
},
|
||||
(**sig_ret_type).clone()
|
||||
}
|
||||
BinaryOp(mut left, op, mut right) => match op {
|
||||
"==" | "!=" => {
|
||||
let left_type = type_check(&mut left, symbols);
|
||||
|
|
Reference in a new issue