From 4b42c59649be8f14fc81dcdc4bf0b86e576fc610 Mon Sep 17 00:00:00 2001 From: Eugen Wissner Date: Wed, 3 Sep 2025 11:16:19 +0200 Subject: [PATCH] Implement binary logical expressions --- boot/stage5.elna | 223 +++++++++++++++++++++++++++++++++++++++++++++- boot/stage6.elna | 225 ++++++++++++++++++++++++++++++++++++++++++++++- 2 files changed, 443 insertions(+), 5 deletions(-) diff --git a/boot/stage5.elna b/boot/stage5.elna index 96ce2e8..3aed6c3 100644 --- a/boot/stage5.elna +++ b/boot/stage5.elna @@ -10,7 +10,9 @@ # The first parameter is in 88, the second in 84 and so forth. # - Unary negate operation, e.g. -5. # - Unary locical not operation "~". -# - Binary addition "+". +# - Binary addition "+" and multiplication "*". +# - Binary logical operations: & (and), or and xor. +# - Binary comparison operations: =, <, <=, >, >=, <>. .section .rodata @@ -86,6 +88,27 @@ asm_neg: .string "\tneg " .type asm_not, @object asm_not: .string "\tnot " +.type asm_and, @object +asm_and: .string "\tand " + +.type asm_or, @object +asm_or: .string "\tor " + +.type asm_xor, @object +asm_xor: .string "\txor " + +.type asm_sub, @object +asm_sub: .string "\tsub " + +.type asm_seqz, @object +asm_seqz: .string "\tseqz " + +.type asm_snez, @object +asm_snez: .string "\tsnez " + +.type asm_slt, @object +asm_slt: .string "\tslt " + .type asm_comma, @object asm_comma: .string ", " @@ -683,7 +706,7 @@ begin _write_c(')'); _write_c('\n'); - # Skip the operator and surrounding whitespaces. + # Skip surrounding whitespace in front of the operator. _advance_token(1); la t0, source_code_position lw t0, (t0) @@ -695,6 +718,24 @@ begin li t1, '*' beq t0, t1, .compile_expression_mul + li t1, '&' + beq t0, t1, .compile_expression_and + + li t1, 'o' + beq t0, t1, .compile_expression_or + + li t1, 'x' + beq t0, t1, .compile_expression_xor + + li t1, '=' + beq t0, t1, .compile_expression_equals + + li t1, '<' + beq t0, t1, .compile_expression_less + + li t1, '>' + beq t0, t1, .compile_expression_greater + # Unknown binary operator. unimp @@ -728,6 +769,184 @@ begin goto .compile_expression_end; +.compile_expression_and: + _advance_token(1); + _compile_binary_rhs(); + + # Execute the operation. + _write_z(@asm_and); + _write_register('t', 0); + _write_z(@asm_comma); + _write_register('t', 0); + _write_z(@asm_comma); + _write_register('t', 1); + _write_c('\n'); + + goto .compile_expression_end; + +.compile_expression_or: + _advance_token(2); + _compile_binary_rhs(); + + # Execute the operation. + _write_z(@asm_or); + _write_register('t', 0); + _write_z(@asm_comma); + _write_register('t', 0); + _write_z(@asm_comma); + _write_register('t', 1); + _write_c('\n'); + + goto .compile_expression_end; + +.compile_expression_xor: + _advance_token(3); + _compile_binary_rhs(); + + # Execute the operation. + _write_z(@asm_xor); + _write_register('t', 0); + _write_z(@asm_comma); + _write_register('t', 0); + _write_z(@asm_comma); + _write_register('t', 1); + _write_c('\n'); + + goto .compile_expression_end; + +.compile_expression_equals: + _advance_token(1); + _compile_binary_rhs(); + + # Execute the operation. + _write_z(@asm_xor); + _write_register('t', 0); + _write_z(@asm_comma); + _write_register('t', 0); + _write_z(@asm_comma); + _write_register('t', 1); + _write_c('\n'); + + _write_z(@asm_seqz); + _write_register('t', 0); + _write_z(@asm_comma); + _write_register('t', 0); + _write_c('\n'); + + goto .compile_expression_end; + +.compile_expression_less: + _advance_token(1); + la t0, source_code_position + lw t0, (t0) + lb t0, (t0) + + li t1, '>' + beq t0, t1, .compile_expression_not_equal + + li t1, '=' + beq t0, t1, .compile_expression_less_equal + + _compile_binary_rhs(); + + # Execute the operation. + _write_z(@asm_slt); + _write_register('t', 0); + _write_z(@asm_comma); + _write_register('t', 0); + _write_z(@asm_comma); + _write_register('t', 1); + _write_c('\n'); + + goto .compile_expression_end; + +.compile_expression_not_equal: + _advance_token(1); + _compile_binary_rhs(); + + # Execute the operation. + _write_z(@asm_xor); + _write_register('t', 0); + _write_z(@asm_comma); + _write_register('t', 0); + _write_z(@asm_comma); + _write_register('t', 1); + _write_c('\n'); + + _write_z(@asm_snez); + _write_register('t', 0); + _write_z(@asm_comma); + _write_register('t', 0); + _write_c('\n'); + + goto .compile_expression_end; + +.compile_expression_less_equal: + _advance_token(1); + _compile_binary_rhs(); + + # Execute the operation. + _write_z(@asm_slt); + _write_register('t', 0); + _write_z(@asm_comma); + _write_register('t', 1); + _write_z(@asm_comma); + _write_register('t', 0); + _write_c('\n'); + + # Execute the operation. + _write_z(@asm_not); + _write_register('t', 0); + _write_z(@asm_comma); + _write_register('t', 0); + _write_c('\n'); + + goto .compile_expression_end; + +.compile_expression_greater: + _advance_token(1); + la t0, source_code_position + lw t0, (t0) + lb t0, (t0) + + li t1, '=' + beq t0, t1, .compile_expression_greater_equal + + _compile_binary_rhs(); + + # Execute the operation. + _write_z(@asm_slt); + _write_register('t', 0); + _write_z(@asm_comma); + _write_register('t', 1); + _write_z(@asm_comma); + _write_register('t', 0); + _write_c('\n'); + + goto .compile_expression_end; + +.compile_expression_greater_equal: + _advance_token(1); + _compile_binary_rhs(); + + # Execute the operation. + _write_z(@asm_slt); + _write_register('t', 0); + _write_z(@asm_comma); + _write_register('t', 0); + _write_z(@asm_comma); + _write_register('t', 1); + _write_c('\n'); + + # Execute the operation. + _write_z(@asm_not); + _write_register('t', 0); + _write_z(@asm_comma); + _write_register('t', 0); + _write_c('\n'); + + goto .compile_expression_end; + .compile_expression_end: end; diff --git a/boot/stage6.elna b/boot/stage6.elna index e9c2ac5..3aed6c3 100644 --- a/boot/stage6.elna +++ b/boot/stage6.elna @@ -10,7 +10,9 @@ # The first parameter is in 88, the second in 84 and so forth. # - Unary negate operation, e.g. -5. # - Unary locical not operation "~". -# - Binary addition "+". +# - Binary addition "+" and multiplication "*". +# - Binary logical operations: & (and), or and xor. +# - Binary comparison operations: =, <, <=, >, >=, <>. .section .rodata @@ -86,6 +88,27 @@ asm_neg: .string "\tneg " .type asm_not, @object asm_not: .string "\tnot " +.type asm_and, @object +asm_and: .string "\tand " + +.type asm_or, @object +asm_or: .string "\tor " + +.type asm_xor, @object +asm_xor: .string "\txor " + +.type asm_sub, @object +asm_sub: .string "\tsub " + +.type asm_seqz, @object +asm_seqz: .string "\tseqz " + +.type asm_snez, @object +asm_snez: .string "\tsnez " + +.type asm_slt, @object +asm_slt: .string "\tslt " + .type asm_comma, @object asm_comma: .string ", " @@ -683,7 +706,7 @@ begin _write_c(')'); _write_c('\n'); - # Skip the operator and surrounding whitespaces. + # Skip surrounding whitespace in front of the operator. _advance_token(1); la t0, source_code_position lw t0, (t0) @@ -695,6 +718,24 @@ begin li t1, '*' beq t0, t1, .compile_expression_mul + li t1, '&' + beq t0, t1, .compile_expression_and + + li t1, 'o' + beq t0, t1, .compile_expression_or + + li t1, 'x' + beq t0, t1, .compile_expression_xor + + li t1, '=' + beq t0, t1, .compile_expression_equals + + li t1, '<' + beq t0, t1, .compile_expression_less + + li t1, '>' + beq t0, t1, .compile_expression_greater + # Unknown binary operator. unimp @@ -728,6 +769,184 @@ begin goto .compile_expression_end; +.compile_expression_and: + _advance_token(1); + _compile_binary_rhs(); + + # Execute the operation. + _write_z(@asm_and); + _write_register('t', 0); + _write_z(@asm_comma); + _write_register('t', 0); + _write_z(@asm_comma); + _write_register('t', 1); + _write_c('\n'); + + goto .compile_expression_end; + +.compile_expression_or: + _advance_token(2); + _compile_binary_rhs(); + + # Execute the operation. + _write_z(@asm_or); + _write_register('t', 0); + _write_z(@asm_comma); + _write_register('t', 0); + _write_z(@asm_comma); + _write_register('t', 1); + _write_c('\n'); + + goto .compile_expression_end; + +.compile_expression_xor: + _advance_token(3); + _compile_binary_rhs(); + + # Execute the operation. + _write_z(@asm_xor); + _write_register('t', 0); + _write_z(@asm_comma); + _write_register('t', 0); + _write_z(@asm_comma); + _write_register('t', 1); + _write_c('\n'); + + goto .compile_expression_end; + +.compile_expression_equals: + _advance_token(1); + _compile_binary_rhs(); + + # Execute the operation. + _write_z(@asm_xor); + _write_register('t', 0); + _write_z(@asm_comma); + _write_register('t', 0); + _write_z(@asm_comma); + _write_register('t', 1); + _write_c('\n'); + + _write_z(@asm_seqz); + _write_register('t', 0); + _write_z(@asm_comma); + _write_register('t', 0); + _write_c('\n'); + + goto .compile_expression_end; + +.compile_expression_less: + _advance_token(1); + la t0, source_code_position + lw t0, (t0) + lb t0, (t0) + + li t1, '>' + beq t0, t1, .compile_expression_not_equal + + li t1, '=' + beq t0, t1, .compile_expression_less_equal + + _compile_binary_rhs(); + + # Execute the operation. + _write_z(@asm_slt); + _write_register('t', 0); + _write_z(@asm_comma); + _write_register('t', 0); + _write_z(@asm_comma); + _write_register('t', 1); + _write_c('\n'); + + goto .compile_expression_end; + +.compile_expression_not_equal: + _advance_token(1); + _compile_binary_rhs(); + + # Execute the operation. + _write_z(@asm_xor); + _write_register('t', 0); + _write_z(@asm_comma); + _write_register('t', 0); + _write_z(@asm_comma); + _write_register('t', 1); + _write_c('\n'); + + _write_z(@asm_snez); + _write_register('t', 0); + _write_z(@asm_comma); + _write_register('t', 0); + _write_c('\n'); + + goto .compile_expression_end; + +.compile_expression_less_equal: + _advance_token(1); + _compile_binary_rhs(); + + # Execute the operation. + _write_z(@asm_slt); + _write_register('t', 0); + _write_z(@asm_comma); + _write_register('t', 1); + _write_z(@asm_comma); + _write_register('t', 0); + _write_c('\n'); + + # Execute the operation. + _write_z(@asm_not); + _write_register('t', 0); + _write_z(@asm_comma); + _write_register('t', 0); + _write_c('\n'); + + goto .compile_expression_end; + +.compile_expression_greater: + _advance_token(1); + la t0, source_code_position + lw t0, (t0) + lb t0, (t0) + + li t1, '=' + beq t0, t1, .compile_expression_greater_equal + + _compile_binary_rhs(); + + # Execute the operation. + _write_z(@asm_slt); + _write_register('t', 0); + _write_z(@asm_comma); + _write_register('t', 1); + _write_z(@asm_comma); + _write_register('t', 0); + _write_c('\n'); + + goto .compile_expression_end; + +.compile_expression_greater_equal: + _advance_token(1); + _compile_binary_rhs(); + + # Execute the operation. + _write_z(@asm_slt); + _write_register('t', 0); + _write_z(@asm_comma); + _write_register('t', 0); + _write_z(@asm_comma); + _write_register('t', 1); + _write_c('\n'); + + # Execute the operation. + _write_z(@asm_not); + _write_register('t', 0); + _write_z(@asm_comma); + _write_register('t', 0); + _write_c('\n'); + + goto .compile_expression_end; + .compile_expression_end: end; @@ -1229,6 +1448,6 @@ begin _read_file(@source_code, 81920); _compile(); - _exit(2 * 3); + _exit(0); end;