Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
11 changes: 11 additions & 0 deletions examples/lop.b
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
main () {
extrn printf;
printf("LOP1: (%d)\n", 1 || 0);
printf("LOP2: (%d)\n", 1 || 1);
printf("LOP3: (%d)\n", 0 || 1);
printf("LOP4: (%d)\n", 0 || 0);
printf("LOP5: (%d)\n", 0 && 1);
printf("LOP6: (%d)\n", 1 && 0);
printf("LOP7: (%d)\n", 1 && 1);
printf("LOP8: (%d)\n", 0 && 0);
}
70 changes: 60 additions & 10 deletions src/b.rs
Original file line number Diff line number Diff line change
Expand Up @@ -237,6 +237,8 @@ pub unsafe fn define_goto_label(c: *mut Compiler, name: *const c_char, loc: Loc,

// The higher the index of the row in this table the higher the precedence of the Binop
pub const PRECEDENCE: *const [*const [Binop]] = &[
&[Binop::LogOr],
&[Binop::LogAnd],
&[Binop::BitOr],
&[Binop::BitAnd],
&[Binop::BitShl, Binop::BitShr],
Expand Down Expand Up @@ -283,6 +285,8 @@ impl Binop {
Token::And => Some(Binop::BitAnd),
Token::Shl => Some(Binop::BitShl),
Token::Shr => Some(Binop::BitShr),
Token::Lor => Some(Binop::LogOr),
Token::Land => Some(Binop::LogAnd),
_ => None,
}
}
Expand Down Expand Up @@ -528,15 +532,61 @@ pub unsafe fn compile_binop_expression(l: *mut Lexer, c: *mut Compiler, preceden
if binop.precedence() != precedence { break; }

let (rhs, _) = compile_binop_expression(l, c, precedence + 1)?;

let index = allocate_auto_var(&mut (*c).auto_vars_ator);
push_opcode(Op::Binop {binop, index, lhs, rhs}, (*l).loc, c);
lhs = Arg::AutoVar(index);

lvalue = false;

saved_point = (*l).parse_point;
lexer::get_token(l)?;
match binop {
Binop::LogOr => {
let result = allocate_auto_var(&mut (*c).auto_vars_ator);

let t_label = allocate_label_index(c);
let e_label = allocate_label_index(c);

push_opcode(Op::Binop { binop: Binop::Equal, index: result, lhs, rhs: Arg::Literal(0) }, (*l).loc, c);
push_opcode(Op::JmpIfNotLabel {label: t_label, arg: Arg::AutoVar(result) }, (*l).loc, c);
push_opcode(Op::Binop { binop: Binop::Equal, index: result, lhs: rhs, rhs: Arg::Literal(0) }, (*l).loc, c);
push_opcode(Op::JmpIfNotLabel {label: t_label, arg: Arg::AutoVar(result) }, (*l).loc, c);
push_opcode(Op::AutoAssign {index: result, arg: Arg::Literal(0)}, (*l).loc, c);
push_opcode(Op::JmpLabel {label: e_label}, (*l).loc, c);

push_opcode(Op::Label {label: t_label}, (*l).loc, c);
push_opcode(Op::AutoAssign {index: result, arg: Arg::Literal(1)}, (*l).loc, c);
push_opcode(Op::Label {label: e_label}, (*l).loc, c);

lhs = Arg::AutoVar(result);
lvalue = false;
saved_point = (*l).parse_point;
lexer::get_token(l)?;
}
Binop::LogAnd => {
let result = allocate_auto_var(&mut (*c).auto_vars_ator);

let t_label = allocate_label_index(c);
let e_label = allocate_label_index(c);

push_opcode(Op::Binop { binop: Binop::Equal, index: result, lhs, rhs: Arg::Literal(1) }, (*l).loc, c);
push_opcode(Op::JmpIfNotLabel {label: t_label, arg: Arg::AutoVar(result) }, (*l).loc, c);
push_opcode(Op::Binop { binop: Binop::Equal, index: result, lhs: rhs, rhs: Arg::Literal(1) }, (*l).loc, c);
push_opcode(Op::JmpIfNotLabel {label: t_label, arg: Arg::AutoVar(result) }, (*l).loc, c);
push_opcode(Op::AutoAssign {index: result, arg: Arg::Literal(1)}, (*l).loc, c);
push_opcode(Op::JmpLabel {label: e_label}, (*l).loc, c);

push_opcode(Op::Label {label: t_label}, (*l).loc, c);
push_opcode(Op::AutoAssign {index: result, arg: Arg::Literal(0)}, (*l).loc, c);
push_opcode(Op::Label {label: e_label}, (*l).loc, c);

lhs = Arg::AutoVar(result);
lvalue = false;
saved_point = (*l).parse_point;
lexer::get_token(l)?;
}
_ => {
let index = allocate_auto_var(&mut (*c).auto_vars_ator);
push_opcode(Op::Binop {binop, index, lhs, rhs}, (*l).loc, c);
lhs = Arg::AutoVar(index);

lvalue = false;
saved_point = (*l).parse_point;
lexer::get_token(l)?;
}
}
}
}
}
Expand All @@ -561,7 +611,7 @@ pub unsafe fn compile_assign_expression(l: *mut Lexer, c: *mut Compiler) -> Opti
}

if let Some(binop) = binop {
compile_binop(lhs, rhs, binop, binop_loc, c);
compile_binop(lhs, rhs, binop, binop_loc, c);
} else {
match lhs {
Arg::Deref(index) => {
Expand Down
4 changes: 3 additions & 1 deletion src/codegen/gas_aarch64/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -188,8 +188,10 @@ pub unsafe fn generate_function(name: *const c_char, _name_loc: Loc, params_coun
},
Op::Binop {binop, index, lhs, rhs} => {
match binop {
Binop::LogAnd => todo!(),
Binop::LogOr => todo!(),
Binop::BitOr => {
load_arg_to_reg(lhs, c!("x0"), output, op.loc, os);
load_arg_to_reg(lhs, c!("x0"), output, op.loc, os);
load_arg_to_reg(rhs, c!("x1"), output, op.loc, os);
sb_appendf(output, c!(" orr x0, x0, x1\n"));
sb_appendf(output, c!(" str x0, [x29, -%zu]\n"), index*8);
Expand Down
9 changes: 6 additions & 3 deletions src/codegen/gas_x86_64/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -179,9 +179,12 @@ pub unsafe fn generate_function(name: *const c_char, name_loc: Loc, func_index:
}
Op::Binop {binop, index, lhs, rhs} => {
load_arg_to_reg(lhs, c!("rax"), output, os);
load_arg_to_reg(rhs, c!("rcx"), output, os);
load_arg_to_reg(rhs, c!("rcx"), output, os);

match binop {
Binop::BitOr => { sb_appendf(output, c!(" orq %%rcx, %%rax\n")); }
Binop::BitOr => {
sb_appendf(output, c!(" orq %%rcx, %%rax\n"));
}
Binop::BitAnd => { sb_appendf(output, c!(" andq %%rcx, %%rax\n")); }
Binop::BitShl => {
load_arg_to_reg(rhs, c!("rcx"), output, os);
Expand Down Expand Up @@ -216,7 +219,7 @@ pub unsafe fn generate_function(name: *const c_char, name_loc: Loc, func_index:
Binop::NotEqual => sb_appendf(output, c!(" setne %%dl\n")),
Binop::GreaterEqual => sb_appendf(output, c!(" setge %%dl\n")),
Binop::LessEqual => sb_appendf(output, c!(" setle %%dl\n")),
_ => unreachable!(),
_ => unreachable!(),
};
sb_appendf(output, c!(" movq %%rdx, -%zu(%%rbp)\n"), index * 8);
continue;
Expand Down
1 change: 1 addition & 0 deletions src/codegen/mos6502.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1270,6 +1270,7 @@ pub unsafe fn generate_function(name: *const c_char, loc: Loc, params_count: usi
// zero extend result
instr8(out, LDY, IMM, 0);
},
_ => unreachable!(),
}
store_auto(out, index, asm);
},
Expand Down
5 changes: 3 additions & 2 deletions src/codegen/uxn/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -335,7 +335,7 @@ pub unsafe fn generate_function(name: *const c_char, name_loc: Loc, params_count
for i in 0..body.len() {
let op = (*body)[i];
match op.opcode {
Op::Bogus => unreachable!("bogus-amogus"),
Op::Bogus => unreachable!("bogus-amogus"),
Op::UnaryNot {result, arg} => {
load_arg(arg, op.loc, output, assembler);
// if arg == 0 then 1 else 0
Expand Down Expand Up @@ -572,7 +572,7 @@ pub unsafe fn generate_function(name: *const c_char, name_loc: Loc, params_count
write_op(output, UxnOp::SFT2);
store_auto(output, index);
}
Op::AutoAssign {index, arg} => {
Op::AutoAssign {index, arg} => {
load_arg(arg, op.loc, output, assembler);
store_auto(output, index);
}
Expand Down Expand Up @@ -653,6 +653,7 @@ pub unsafe fn generate_function(name: *const c_char, name_loc: Loc, params_count
write_op(output, UxnOp::ADD2);
store_auto(output, result);
},
_ => unreachable!()
}
}

Expand Down
4 changes: 4 additions & 0 deletions src/ir.rs
Original file line number Diff line number Diff line change
Expand Up @@ -50,6 +50,8 @@ pub enum Binop {
BitAnd,
BitShl,
BitShr,
LogOr,
LogAnd,
}

#[derive(Clone, Copy)]
Expand Down Expand Up @@ -200,6 +202,8 @@ pub unsafe fn dump_op(op: OpWithLocation, output: *mut String_Builder) {
sb_appendf(output, c!(" auto[%zu] = "), index);
dump_arg(output, lhs);
match binop {
Binop::LogAnd => sb_appendf(output, c!(" && ")),
Binop::LogOr => sb_appendf(output, c!(" || ")),
Binop::BitOr => sb_appendf(output, c!(" | ")),
Binop::BitAnd => sb_appendf(output, c!(" & ")),
Binop::BitShl => sb_appendf(output, c!(" << ")),
Expand Down
8 changes: 7 additions & 1 deletion src/lexer.rs
Original file line number Diff line number Diff line change
Expand Up @@ -80,7 +80,9 @@ pub enum Token {
Colon,
SemiColon,
Comma,

Lor, // ||
Land, // &&

// Keywords
Auto,
Extrn,
Expand Down Expand Up @@ -146,6 +148,8 @@ pub unsafe fn display_token(token: Token) -> *const c_char {
Token::Colon => c!("`:`"),
Token::SemiColon => c!("`;`"),
Token::Comma => c!("`,`"),
Token::Lor => c!("`||`"),
Token::Land => c!("`&&`"),

Token::Auto => c!("keyword `auto`"),
Token::Extrn => c!("keyword `extrn`"),
Expand Down Expand Up @@ -193,8 +197,10 @@ pub const PUNCTS: *const [(*const c_char, Token)] = &[
(c!("/="), Token::DivEq),
(c!("/"), Token::Div),
(c!("|="), Token::OrEq),
(c!("||"), Token::Lor),
(c!("|"), Token::Or),
(c!("&="), Token::AndEq),
(c!("&&"), Token::Land),
(c!("&"), Token::And),
(c!("=="), Token::EqEq),
(c!("="), Token::Eq),
Expand Down