program import dummy const SOURCE_BUFFER_SIZE := 81920 var source_code: [81920]Byte (* Ignores the import. *) proc _compile_import() var loca0: Word begin _advance(6); _skip_spaces(); loca0 := _read_token(); _advance(loca0) end proc _build_binary_expression() var loca0, loca4, loca8, loca16, loca20: Word loca12: ^Byte loca24: Bool begin _build_expression(0); loca4 := 0x2c306120; loca8 := 0x0a316120; _skip_spaces(); loca20 := _read_token(); loca12 := _current(); loca16 := 0x26; loca24 := _token_compare(loca12, loca20, @loca16); if loca24 = 0 then goto .L_build_binary_expression_and end; loca16 := 0x726f; loca24 := _token_compare(loca12, loca20, @loca16); if loca24 = 0 then goto .L_build_binary_expression_or end; loca16 := 0x3d; loca24 := _token_compare(loca12, loca20, @loca16); if loca24 = 0 then goto .L_build_binary_expression_equal end; loca16 := 0x2b; loca24 := _token_compare(loca12, loca20, @loca16); if loca24 = 0 then goto .L_build_binary_expression_plus end; loca16 := 0x2d; loca24 := _token_compare(loca12, loca20, @loca16); if loca24 = 0 then goto .L_build_binary_expression_minus end loca16 := 0x2a; loca24 := _token_compare(loca12, loca20, @loca16); if loca24 = 0 then goto .L_build_binary_expression_product end; goto .Lbuild_binary_expression_end; .L_build_binary_expression_equal; _advance(1); _build_expression(1); loca0 := 0x627573; _write_out(@loca0, 3); _write_out(@loca4, 4); _write_out(@loca4, 4); _write_out(@loca8, 4); loca0 := 0x7a716573; _write_out(@loca0, 4); _write_out(@loca4, 4); _write_out(@loca4, 3); _put_char(0x0a); goto .Lbuild_binary_expression_end; .L_build_binary_expression_and; _advance(1); _build_expression(1); loca0 := 0x646e61; _write_out(@loca0, 3); _write_out(@loca4, 4); _write_out(@loca4, 4); _write_out(@loca8, 4); goto .Lbuild_binary_expression_end; .L_build_binary_expression_or; _advance(2); _build_expression(1); loca0 := 0x726f; _write_out(@loca0, 2); _write_out(@loca4, 4); _write_out(@loca4, 4); _write_out(@loca8, 4); goto .Lbuild_binary_expression_end; .L_build_binary_expression_plus; _advance(1); _build_expression(1); loca0 := 0x646461; _write_out(@loca0, 3); _write_out(@loca4, 4); _write_out(@loca4, 4); _write_out(@loca8, 4); goto .Lbuild_binary_expression_end; .L_build_binary_expression_minus; _advance(1); _build_expression(1); loca0 := 0x627573; _write_out(@loca0, 3); _write_out(@loca4, 4); _write_out(@loca4, 4); _write_out(@loca8, 4); goto .Lbuild_binary_expression_end; .L_build_binary_expression_product; _advance(1); _build_expression(1); loca0 := 0x6c756d; _write_out(@loca0, 3); _write_out(@loca4, 4); _write_out(@loca4, 4); _write_out(@loca8, 4); goto .Lbuild_binary_expression_end; .Lbuild_binary_expression_end end proc _compile_identifier_expression(loca84: Word, loca80: Byte) begin loca24 := _current(); loca0 := 0x61636f6c; loca0 := _memcmp(@loca0, loca24, 4); if loca0 = 0 then loca8 := 0x6120776c; _write_out(@loca8, 4); loca8 := 0x00202c00 or loca80; _write_out(@loca8, 3); loca4 := loca24 + 4; loca0 := loca84 - 4; _write_out(loca4, loca0); loca8 := 0x29707328; _write_out(@loca8, 4); _put_char(0x0a); goto .Lcompile_identifier_expression_end end; loca0 := _front(loca24); loca8 := loca84 = 2; loca12 := loca0 = 0x73; if loca8 & loca12 then loca8 := 0x6120766d; _write_out(@loca8, 4); loca8 := 0x00202c00 or loca80; _write_out(@loca8, 3); _write_out(loca24, loca84); _put_char(0x0a); goto .Lcompile_identifier_expression_end end (* Global identifier. *); loca8 := 0x6120616c; _write_out(@loca8, 4); loca8 := 0x00202c00 or loca80; _write_out(@loca8, 3); _write_out(loca24, loca84); _put_char(0x0a); if _is_upper(loca0) then loca8 := 0x6120776c; _write_out(@loca8, 4); loca8 := 0x28202c00 or loca28; _write_out(@loca8, 4); _put_char(0x61); _put_char(loca28); _put_char(0x29); _put_char(0x0a); goto .Lcompile_identifier_expression_end end; .Lcompile_identifier_expression_end end (* Evalutes an expression and saves the result in a0. a0 - X in aX, the register number to save the result. *) proc _build_expression() var loca0, loca20, loca28, loca8: Word loca24, loca4: ^Byte begin loca28 := loca84 + 0x30; _skip_spaces(); loca20 := _read_token(); loca24 := _current(); loca0 := _front(loca24); if loca0 = 0x2d then goto .Lbuild_expression_negate end; if loca0 = 0x40 then goto .Lbuild_expression_address end; if _is_digit(loca0) then goto .Lbuild_expression_literal end; if loca0 = 0x5f then goto .Lbuild_expression_call end; _compile_identifier_expression(loca20, loca28); goto .Lbuild_expression_advance; .Lbuild_expression_negate; _advance(1); _build_expression(0); loca8 := 0x2067656e; _write_out(@loca8, 4); loca8 := 0x202c3061; _write_out(@loca8, 4); loca8 := 0x0a3061; _write_out(@loca8, 3); goto .Lbuild_expression_advance; .Lbuild_expression_address; loca8 := 0x69646461; _write_out(@loca8, 4); loca8 := 0x6120; _write_out(@loca8, 2); _put_char(loca28); loca8 := 0x7073202c; _write_out(@loca8, 4); loca8 := 0x202c; _write_out(@loca8, 2); _advance(1); _skip_spaces(); loca24 := _current(); loca20 := _read_token(); loca4 := loca24 + 4; loca0 := loca20 - 4; _write_out(loca4, loca0); _put_char(0xa); goto .Lbuild_expression_advance; .Lbuild_expression_call; _advance(loca20); _advance(1); _compile_call(loca24, loca20); goto .Lbuild_expression_end; .Lbuild_expression_literal; loca8 := 0x6120696c; _write_out(@loca8, 4); loca8 := 0x00202c00 or loca28; _write_out(@loca8, 3); _write_out(loca24, loca20); _put_char(0x0a); goto .Lbuild_expression_advance; .Lbuild_expression_advance; _advance(loca20); .Lbuild_expression_end end (* Compiles an lvalue. Parameters: a0 - Pointer to the identifier. a1 - Identifier length. *) proc _compile_designator_expression(loca84: ^Byte, loca80: Word) var loca0: Word begin loca0 := 0x61636f6c; loca4 := _memcmp(@loca0, loca84, 4); if loca4 = 0 then loca0 := 0x61207773; _write_out(@loca0, 4); loca0 := 0x202c30; _write_out(@loca0, 3); loca84 := loca84 + 4; loca80 := loca80 - 4; _write_out(loca84, loca80); loca0 := 0x29707328; _write_out(@loca0, 4); _put_char(0x0a); goto .Lcompile_designator_expression_end end; loca8 := _front(loca84); loca12 := loca8 = 0x73; loca16 := loca80 = 2; if loca12 & loca16 then loca0 := 0x20766d; _write_out(@loca0, 3); _write_out(loca84, loca80); loca0 := 0x3061202c; _write_out(@loca0, 4); _put_char(0x0a); goto .Lcompile_designator_expression_end end; .Lcompile_designator_expression_end end (* Compiles a statement beginning with an identifier. Left values should be variables named "loca n", where n is the offset of the variable on the stack, like loca8 or loca4. *) proc _compile_identifier() var loca0, loca16, loca8: Word loca20, loca12: ^Byte loca4: Bool begin loca20 := _current(); loca16 := _read_token(); _advance(loca16); _skip_spaces(); loca12 := _current(); loca8 := _read_token(); _advance(loca8); _skip_spaces(); loca0 := 0x3d3a; loca4 := _token_compare(loca12, loca8, @loca0); if loca4 = 0 then _build_binary_expression(); _compile_designator_expression(loca20, loca16); goto .Lcompile_identifier_end end; if _front(loca12) = 0x28 then _compile_call(loca20, loca16); goto .Lcompile_identifier_end end; .Lcompile_identifier_end end (* Compiles a procedure call. Expects s1 to point to the first argument. a0 - Pointer to the procedure name. a1 - Length of the procedure name. Returns the procedure result in a0. *) proc _compile_call(loca84: ^Byte, loca80: Word) var loca0, loca4, loca12: Word loca8: ^Byte begin loca12 := 0; .Lcompile_call_paren; _skip_spaces(); loca8 := _current(); if _front(loca8) = 0x29 then goto .Lcompile_call_complete end; .Lcompile_call_argument; _build_expression(0); loca0 := 0x61207773; _write_out(@loca0, 4); loca0 := 0x202c30; _write_out(@loca0, 3); (* Only 6 arguments are supported with a0-a5. Save all arguments on the stack so they aren't overriden afterwards. *) loca0 := -4 * loca12; loca0 := loca0 + 60; _printi(loca0); loca0 := 0x29707328; _write_out(@loca0, 4); _put_char(0x0a); _skip_spaces(); loca8 := _current(); loca0 := _front(loca8) = 0x2c; if loca0 = 0 then goto .Lcompile_call_paren end loca12 := loca12 + 1; _advance(1); goto .Lcompile_call_argument; .Lcompile_call_complete; loca12 := 0; .Lcompile_call_restore; (* Just go through all a0-a5 registers and read them from stack. If this stack value contains garbage, the procedure just shouldn't use it. *) loca0 := 0x6120776c; _write_out(@loca0, 4); loca4 := 0x36202c30; _write_out(@loca4, 4); loca4 := 0x70732830; _write_out(@loca4, 4); loca4 := 0x0a29; _write_out(@loca4, 2); _write_out(@loca0, 4); loca4 := 0x35202c31; _write_out(@loca4, 4); loca4 := 0x70732836; _write_out(@loca4, 4); loca4 := 0x0a29; _write_out(@loca4, 2); _write_out(@loca0, 4); loca4 := 0x35202c32; _write_out(@loca4, 4); loca4 := 0x70732832; _write_out(@loca4, 4); loca4 := 0x0a29; _write_out(@loca4, 2); _write_out(@loca0, 4); loca4 := 0x34202c33; _write_out(@loca4, 4); loca4 := 0x70732838; _write_out(@loca4, 4); loca4 := 0x0a29; _write_out(@loca4, 2); _write_out(@loca0, 4); loca4 := 0x34202c34; _write_out(@loca4, 4); loca4 := 0x70732834; _write_out(@loca4, 4); loca4 := 0x0a29; _write_out(@loca4, 2); _write_out(@loca0, 4); loca4 := 0x34202c35; _write_out(@loca4, 4); loca4 := 0x70732830; _write_out(@loca4, 4); loca4 := 0x0a29; _write_out(@loca4, 2); loca0 := 0x6c6c6163; _write_out(@loca0, 4); _put_char(0x20); _write_out(loca84, loca80); _put_char(0x0a); _skip_spaces(); _advance(1) end (* Reads a token and returns its length in a0. _read_token doesn't change s1, it finds the length of the token s1 is pointing to. *) proc _read_token() var loca0, loca4: Word loca8: ^Byte begin loca8 := _current(); loca0 := _front(loca8); loca4 := 0; if loca0 = 0x2e then goto .Ltoken_character_single end; if loca0 = 0x2c then goto .Ltoken_character_single end; if loca0 = 0x3a then goto .Ltoken_character_colon end; if loca0 = 0x3b then goto .Ltoken_character_single end; if loca0 = 0x28 then goto .Ltoken_character_single end; if loca0 = 0x29 then goto .Ltoken_character_single end; if loca0 = 0x5b then goto .Ltoken_character_single end; if loca0 = 0x5d then goto .Ltoken_character_single end; if loca0 = 0x5e then goto .Ltoken_character_single end; if loca0 = 0x26 then goto .Ltoken_character_single end; if loca0 = 0x3d then goto .Ltoken_character_single end; if loca0 = 0x2b then goto .Ltoken_character_single end; if loca0 = 0x2d then goto .Ltoken_character_single end; if loca0 = 0x2a then goto .Ltoken_character_single end; if loca0 = 0x40 then goto .Ltoken_character_single end; .Ltoken_character_loop_do; loca0 := loca8 + loca4; loca0 := _front(loca0); if _is_alnum(loca0) then loca4 := loca4 + 1; goto .Ltoken_character_loop_do; .Ltoken_character_single; loca4 := loca4 + 1; goto .Ltoken_character_end; .Ltoken_character_colon; loca0 := loca8 + 1; loca0 := _front(loca0); loca4 := loca4 + 1; if loca0 = 0x3d then goto .Ltoken_character_single end end; .Ltoken_character_end; return loca4 end (* Skips the spaces till the next non space character. *) proc _skip_spaces() var loca0: Byte loca4: ^Byte begin .Lspace_loop_do; loca4 := _current(); loca0 := _front(loca4); if loca0 = 0x20 then goto .Lspace_loop_repeat end; if loca0 = 0x09 then goto .Lspace_loop_repeat end; if loca0 = 0x0a then goto .Lspace_loop_repeat end; if loca0 = 0x0d then goto .Lspace_loop_repeat end; goto .Lspace_loop_end; .Lspace_loop_repeat; _advance(1); goto .Lspace_loop_do; .Lspace_loop_end end (* Parameters: a0 - Line length. *) proc _skip_comment(loca84: Word) var loca0: ^Byte loca4: Word loca8: Int begin loca0 := _current(); loca4 := 0x2a28; loca8 := _memcmp(loca0, @loca4, 2); if loca8 = 0 then goto .Lskip_comment_continue end; goto .Lskip_comment_end; .Lskip_comment_continue; _advance(2); loca4 := 0x292a; .Lskip_comment_loop; loca0 := _current(); loca8 := _memcmp(loca0, @loca4, 2); if loca8 = 0 then goto .Lskip_comment_close end; _advance(1); goto .Lskip_comment_loop; .Lskip_comment_close; _advance(2); .Lskip_comment_end end (* Parameters: a0 - Line length. *) proc _compile_assembly(loca84: Word) var loca0: ^Byte begin loca0 := _current(); _write_out(loca0, loca84); _advance(loca84); _put_char(0xa); _advance(1) end proc _compile_program() var loca0: Word begin loca0 := 0x6f6c672e; _write_out(@loca0, 4); loca0 := 0x206c6162; _write_out(@loca0, 4); loca0 := 0x6174735f; _write_out(@loca0, 4); loca0 := 0x0a7472; _write_out(@loca0, 3); _advance(8) end proc _compile_constant_section() var loca0: Word loca4: ^Byte begin loca0 := 0x6365732e; _write_out(@loca0, 4); loca0 := 0x6e6f6974; _write_out(@loca0, 4); loca0 := 0x6f722e20; _write_out(@loca0, 4); loca0 := 0x61746164; _write_out(@loca0, 4); loca0 := 0x0a; _write_out(@loca0, 1); _advance(6); .Lcompile_constant_section_item; _skip_spaces(); loca4 := _current(); loca0 := _front(loca4); if _is_upper(loca0) then _compile_constant(); goto .Lcompile_constant_section_item end; .Lcompile_constant_section_end end proc _compile_constant() var loca0, loca4: Word loca8: ^Byte begin loca4 := _read_token(); loca8 := _current(); _write_out(loca8, loca4); _advance(loca4); _skip_spaces(); _advance(2); loca0 := 0x6c2e203a; _write_out(@loca0, 4); loca0 := 0x20676e6f; _write_out(@loca0, 4); _skip_spaces(); loca4 := _read_token(); loca8 := _current(); _write_out(loca8, loca4); _advance(loca4); _put_char(0x0a) end proc _compile_variable_section() var loca0: Word loca4: ^Byte begin loca0 := 0x6365732e; _write_out(@loca0, 4); loca0 := 0x6e6f6974; _write_out(@loca0, 4); loca0 := 0x73622e20; _write_out(@loca0, 4); loca0 := 0x0a73; _write_out(@loca0, 2); _advance(4); .Lcompile_variable_section_item; _skip_spaces(); loca4 := _current(); loca0 := _front(loca4); if _is_lower(loca0) = 0 then goto .Lcompile_variable_section_end end; _compile_variable(); goto .Lcompile_variable_section_item; .Lcompile_variable_section_end end proc _compile_variable() var loca28, loca16: ^Byte loca0, loca24, loca20: Word begin loca24 := _read_token(); loca28 := _current(); _advance(loca24); _skip_spaces(); _advance(1); _skip_spaces(); _advance(1); loca16 := _read_token(); loca20 := _current(); _advance(loca16); _skip_spaces(); _advance(1); _skip_spaces(); loca0 := _read_token(); _advance(loca0); loca0 := 0x7079742e; _write_out(@loca0, 4); loca0 := 0x2065; _write_out(@loca0, 2); _write_out(loca28, loca24); loca0 := 0x6f40202c; _write_out(@loca0, 4); loca0 := 0x63656a62; _write_out(@loca0, 4); loca0 := 0x0a74; _write_out(@loca0, 2); (* .size identifier, size *); loca0 := 0x7a69732e; _write_out(@loca0, 4); loca0 := 0x2065; _write_out(@loca0, 2); _write_out(loca28, loca24); loca0 := 0x202c; _write_out(@loca0, 2); _write_out(loca20, loca16); _put_char(0x0a); _write_out(loca28, loca24); loca0 := 0x7a2e203a; _write_out(@loca0, 4); loca0 := 0x206f7265; _write_out(@loca0, 4); _write_out(loca20, loca16); _put_char(0x0a) end proc _compile_procedure() var loca0, loca4, loca8, loca12, loca16: Word loca20, loca24: ^Byte begin _advance(5); loca16 := _read_token(); loca20 := _current(); _advance(loca16); (* .type identifier, @function *); loca0 := 0x7079742e; _write_out(@loca0, 4); loca0 := 0x2065; _write_out(@loca0, 2); _write_out(loca20, loca16); loca0 := 0x6640202c; _write_out(@loca0, 4); loca0 := 0x74636e75; _write_out(@loca0, 4); loca0 := 0x0a6e6f69; _write_out(@loca0, 4); _write_out(loca20, loca16); loca0 := 0x0a3a; _write_out(@loca0, 2); _skip_spaces(); _advance(1); _skip_spaces(); _advance(1); loca12 := 0x6e; loca8 := 0x69676562; (* Skip all declarations until we find the "begin" keyword, denoting the beginning of the procedure body. *) .Lcompile_procedure_begin; _skip_spaces(); loca0 := _read_token(); loca24 := _current(); _advance(loca0); loca0 := _token_compare(loca24, loca0, @loca8); if loca0 = 1 then goto .Lcompile_procedure_begin end; loca0 := 0x69646461; _write_out(@loca0, 4); loca0 := 0x2c707320; _write_out(@loca0, 4); _write_out(@loca0, 4); loca0 := 0x0a36392d; _write_out(@loca0, 4); loca0 := 0x72207773; _write_out(@loca0, 4); loca0 := 0x39202c61; _write_out(@loca0, 4); loca0 := 0x70732832; _write_out(@loca0, 4); loca0 := 0x0a29; _write_out(@loca0, 2); loca0 := 0x73207773; _write_out(@loca0, 4); loca0 := 0x38202c30; _write_out(@loca0, 4); loca0 := 0x70732838; _write_out(@loca0, 4); loca0 := 0x0a29; _write_out(@loca0, 2); loca0 := 0x69646461; _write_out(@loca0, 4); loca0 := 0x2c307320; _write_out(@loca0, 4); loca0 := 0x2c707320; _write_out(@loca0, 4); loca0 := 0x0a363920; _write_out(@loca0, 4); loca0 := 0x61207773; _write_out(@loca0, 4); loca4 := 0x38202c30; _write_out(@loca4, 4); loca8 := 0x70732834; _write_out(@loca8, 4); loca12 := 0x0a29; _write_out(@loca12, 2); _write_out(@loca0, 4); loca4 := 0x38202c31; _write_out(@loca4, 4); loca8 := 0x70732830; _write_out(@loca8, 4); _write_out(@loca12, 2); _write_out(@loca0, 4); loca4 := 0x37202c32; _write_out(@loca4, 4); loca8 := 0x70732836; _write_out(@loca8, 4); _write_out(@loca12, 2); _write_out(@loca0, 4); loca4 := 0x37202c33; _write_out(@loca4, 4); loca8 := 0x70732832; _write_out(@loca8, 4); _write_out(@loca12, 2); _write_out(@loca0, 4); loca4 := 0x36202c34; _write_out(@loca4, 4); loca8 := 0x70732838; _write_out(@loca8, 4); _write_out(@loca12, 2); _write_out(@loca0, 4); loca4 := 0x36202c35; _write_out(@loca4, 4); loca8 := 0x70732838; _write_out(@loca8, 4); _write_out(@loca12, 2); .Lcompile_procedure_body; _skip_spaces(); loca12 := _read_line(); loca8 := 0x0a646e65; loca24 := _current(); loca8 := _memcmp(loca24, @loca8, 4); if loca8 = 0 then goto .Lcompile_procedure_end end; _compile_line(loca12); goto .Lcompile_procedure_body; .Lcompile_procedure_end; _advance(4); loca0 := 0x7220776c; _write_out(@loca0, 4); loca0 := 0x39202c61; _write_out(@loca0, 4); loca0 := 0x70732832; _write_out(@loca0, 4); loca0 := 0x0a29; _write_out(@loca0, 2); loca0 := 0x7320776c; _write_out(@loca0, 4); loca0 := 0x38202c30; _write_out(@loca0, 4); loca0 := 0x70732838; _write_out(@loca0, 4); loca0 := 0x0a29; _write_out(@loca0, 2); loca0 := 0x69646461; _write_out(@loca0, 4); loca0 := 0x2c707320; _write_out(@loca0, 4); _write_out(@loca0, 4); loca0 := 0x0a3639; _write_out(@loca0, 4); loca0 := 0x0a746572; _write_out(@loca0, 4) end (* Compares two string, which of one has a length, the other one is null-terminated. a0 - The address of the token string. a1 - The length of the string in a0. a2 - The address of the null-terminated string. If the strings match sets a0 to 0, otherwise sets it to 1. *) proc _token_compare(loca84: ^Byte, loca80: Word, loca76: ^Byte) var loca0: Bool loca4, loca12: Byte loca8: Word begin .Ltoken_compare_loop; loca4 := _front(loca76); (* Will only be 0 if the current character in the null terminated string is \0 and the remaining length of the another string is 0. *) loca8 := loca4 or loca80; if loca8 = 0 then goto .Ltoken_compare_equal end; if loca80 = 0 then goto .Ltoken_compare_not_equal end; if loca4 = 0 then goto .Ltoken_compare_not_equal end; loca12 := _front(loca84); if loca4 = loca12 then goto .Ltoken_compare_continue end; goto .Ltoken_compare_not_equal; .Ltoken_compare_continue; loca84 := loca84 + 1; loca80 := loca80 - 1; loca76 := loca76 + 1; goto .Ltoken_compare_loop; .Ltoken_compare_not_equal; loca0 := 1; goto .Ltoken_compare_end; .Ltoken_compare_equal; loca0 := 0; .Ltoken_compare_end; return loca0 end proc _compile_goto() var loca0: Word loca8: ^Byte begin _advance(4); loca0 := 0x206a; _write_out(@loca0, 2); _skip_spaces(); loca8 := _current(); _advance(1); loca0 := _read_token(); _advance(loca0); loca0 := loca0 + 1; _write_out(loca8, loca0); _advance(1); _put_char(0x0a) end (* a0 - Line length. *) proc _compile_label(loca84: Word) var loca0: Word begin loca0 := _current(); loca0 := loca0 + loca84; loca0 := loca0 - 1; loca4 := loca84; loca0 := _front(loca0); if loca0 = 0x3b then loca4 := loca4 - 1 end; _write_out(s1, loca4); _put_char(0x3a); _put_char(0x0a); _advance(loca84) end proc _compile_return() begin _advance(6); _skip_spaces(); _build_binary_expression(); end proc _compile_if() var loca8, loca12, loca16, loca20: Word loca4: ^Byte begin _advance(2); _skip_spaces(); _build_binary_expression(); _skip_spaces(); _advance(4); loca20 := 0x00646e65; loca16 := 0x66694c2e; loca12 := 0x7a716562; _write_out(@loca12, 4); loca12 := 0x2c306120; _write_out(@loca12, 4); _put_char(0x20); (* Write the label *); _write_out(@loca16, 4); _printi(s2); _put_char(0x0a); .Lcompile_if_loop; _skip_spaces(); loca12 := _read_token(); loca4 := _current(); loca8 := _token_compare(loca4, loca12, @loca20); if loca8 then loca12 := _read_line(); _compile_line(loca12, 1); goto .Lcompile_if_loop end; _write_out(@loca16, 4); _printi(s2); loca12 := 0x0a3a0a3a; _write_out(@loca12, 2); (* Increment the label counter. *); s2 := s2 + 1; _advance(4) end (* Parameters: a0 - Line length. a1 - Whether the section header was already emitted. If not it should be emitted before any code is written. Returns 1 in a0 if the parsed line contained a text section element such a procedure or the program entry point. Otherwise sets a0 to 0. *) proc _compile_line(loca84: Word, loca80: Bool) var loca0: Char loca4: Int loca8: Bool loca12: Word loca16: ^Byte begin if loca84 = 0 then goto .Lcompile_line_empty end; loca16 := _current(); loca0 := _front(loca16); if loca0 = 0x28 then goto .Lcompile_line_comment end; loca16 := _current(); loca12 := 0x676f7270; loca4 := _memcmp(loca16, @loca12, 4); if loca4 = 0 then goto .Lcompile_line_program end; loca12 := 0x736e6f63; loca4 := _memcmp(loca16, @loca12, 4); if loca4 = 0 then goto .Lcompile_line_const end; loca12 := 0x0a726176; loca4 := _memcmp(loca16, @loca12, 4); if loca4 = 0 then goto .Lcompile_line_var end; loca12 := 0x636f7270; loca4 := _memcmp(loca16, @loca12, 4); if loca4 = 0 then goto .Lcompile_line_procedure end; loca12 := 0x69676562; loca4 := _memcmp(loca16, @loca12, 4); if loca4 = 0 then goto .Lcompile_line_begin end; loca12 := 0x2e646e65; loca4 := _memcmp(loca16, @loca12, 4); if loca4 = 0 then goto .Lcompile_line_exit end; loca12 := 0x61636f6c; loca4 := _memcmp(loca16, @loca12, 4); if loca4 = 0 then goto .Lcompile_line_identifier end; loca4 := _front(loca16); if loca4 = 0x73 then goto .Lcompile_line_identifier end; loca12 := 0x6f706d69; loca4 := _memcmp(loca16, @loca12, 4); if loca4 = 0 then goto .Lcompile_line_import end; loca12 := 0x6f746f67; loca4 := _memcmp(loca16, @loca12, 4); if loca4 = 0 then goto .Lcompile_line_goto end; loca12 := 0x75746572; loca4 := _memcmp(loca16, @loca12, 4); if loca4 = 0 then goto .Lcompile_line_return end; loca12 := 0x6669; loca4 := _memcmp(loca16, @loca12, 2); if loca4 = 0 then goto .Lcompile_line_if end; if loca0 = 0x2e then goto .Lcompile_line_label end; if loca0 = 0x5f then goto .Lcompile_line_identifier end; goto .Lcompile_line_unchanged; .Lcompile_line_if; _compile_if(); goto .Lcompile_line_section; .Lcompile_line_label; _compile_label(loca84); goto .Lcompile_line_section; .Lcompile_line_return; _compile_return(); goto .Lcompile_line_section; .Lcompile_line_goto; _compile_goto(); goto .Lcompile_line_section; .Lcompile_line_import; _compile_import(); goto .Lcompile_line_section; .Lcompile_line_identifier; _compile_identifier(); goto .Lcompile_line_section; .Lcompile_line_exit; _compile_exit(); goto .Lcompile_line_section; .Lcompile_line_begin; if loca80 = 1 then goto .Lcompile_line_compile_entry end; _compile_text_section(); .Lcompile_line_compile_entry; _compile_entry_point(); loca8 := 1; goto .Lcompile_line_end; .Lcompile_line_const; _compile_constant_section(); goto .Lcompile_line_section; .Lcompile_line_procedure; if loca80 = 1 then goto .Lcompile_line_compile_procedure end; _compile_text_section(); .Lcompile_line_compile_procedure; _compile_procedure(); loca8 := 1; goto .Lcompile_line_end; .Lcompile_line_var; _compile_variable_section(); goto .Lcompile_line_section; .Lcompile_line_program; _compile_program(); goto .Lcompile_line_section; .Lcompile_line_comment; _skip_comment(loca84); goto .Lcompile_line_section; .Lcompile_line_empty; _advance(1); goto .Lcompile_line_section; .Lcompile_line_unchanged; _compile_assembly(loca84); goto .Lcompile_line_section; .Lcompile_line_section; loca8 := 0; .Lcompile_line_end; _skip_spaces(); _skip_comment(); return loca8 end (* Prints ".section .text" and exits. *) proc _compile_text_section() var loca0: Word begin loca0 := 0x6365732e; _write_out(@loca0, 4); loca0 := 0x6e6f6974; _write_out(@loca0, 4); loca0 := 0x65742e20; _write_out(@loca0, 4); loca0 := 0x0a7478; _write_out(@loca0, 3) end proc _compile_entry_point() var loca0: Word begin loca0 := 0x7079742e; _write_out(@loca0, 4); loca0 := 0x735f2065; _write_out(@loca0, 4); loca0 := 0x74726174; _write_out(@loca0, 4); loca0 := 0x6640202c; _write_out(@loca0, 4); loca0 := 0x74636e75; _write_out(@loca0, 4); loca0 := 0x0a6e6f69; _write_out(@loca0, 4); loca0 := 0x6174735f; _write_out(@loca0, 4); loca0 := 0x0a3a7472; _write_out(@loca0, 4); _advance(6) end proc _compile_exit() var loca0: Word begin loca0 := 0x6120696c; _write_out(@loca0, 4); loca0 := 0x30202c30; _write_out(@loca0, 4); loca0 := 0x20696c0a; _write_out(@loca0, 4); loca0 := 0x202c3761; _write_out(@loca0, 4); loca0 := 0x650a3339; _write_out(@loca0, 4); loca0 := 0x6c6c6163; _write_out(@loca0, 4); loca0 := 0x0a; _write_out(@loca0, 1); _advance(4); _skip_spaces() end (* Finds the end of the line and returns its length in a0. *) proc _read_line() var loca0: ^Byte loca4: Byte begin loca0 := _current(); .Lread_line_do; loca4 := _front(loca0); if loca4 = 0 then goto .Lread_line_end end; if loca4 = 0x0a then goto .Lread_line_end end; loca0 := loca0 + 1; goto .Lread_line_do; .Lread_line_end; loca4 := _current(); return loca0 - loca4 end proc _compile() var loca0, loca4: Word loca8: Bool loca12: Char loca16: ^Byte begin loca4 := 0; .Lcompile_do; loca16 := _current(); loca12 := _front(loca16); if loca12 = 0 then goto .Lcompile_end end; _skip_spaces(); loca0 := _read_line(); loca8 := _compile_line(loca0, loca4); if loca8 = 0 then goto .Lcompile_do end; loca4 := loca4 or loca8; goto .Lcompile_do; .Lcompile_end end (* Returns the pointer to the current position in the source text in a0. *) proc _current() begin return s1 end (* a0 is the number of bytes to advance in the source text. *) proc _advance(loca84: Word) begin s1 := s1 + loca84 end (* a0 - Pointer to an array to get the first element. Returns the first character in the remaining source text. *) proc _front(loca84: ^Word) begin return _get(loca84) & 0xff end proc _main() begin _read_file(source_code, SOURCE_BUFFER_SIZE); s2 := 1 end (* Entry point. *) begin _main(); _compile() end.