Add an empty cstdlib.elna source file
This commit is contained in:
		| @@ -6,9 +6,7 @@ module; | |||||||
| from Args import GetArg, Narg; | from Args import GetArg, Narg; | ||||||
| from FIO import WriteString, WriteChar, WriteLine, StdErr; | from FIO import WriteString, WriteChar, WriteLine, StdErr; | ||||||
| from Strings import CompareStr, Length; | from Strings import CompareStr, Length; | ||||||
| from MemUtils import MemZero; | import cstdlib, common; | ||||||
|  |  | ||||||
| from Common import ShortString; |  | ||||||
|  |  | ||||||
| type | type | ||||||
|   CommandLine = record |   CommandLine = record | ||||||
| @@ -29,26 +27,26 @@ begin | |||||||
|   NEW(result); |   NEW(result); | ||||||
|   result^.lex := false; |   result^.lex := false; | ||||||
|   result^.parse := false; |   result^.parse := false; | ||||||
|   MemZero(@result^.input, 256); |   memset(@result^.input, 0, 256); | ||||||
|   result^.output[1] := CHAR(0); |   result^.output[1] := CHAR(0); | ||||||
|  |  | ||||||
|   while (i < Narg()) & (result <> nil) do |   while (i < Narg()) & (result <> nil) do | ||||||
|     parsed := GetArg(parameter, i); |     parsed := GetArg(parameter, i); | ||||||
|     parsed := false; |     parsed := false; | ||||||
|  |  | ||||||
|     if CompareStr(parameter, '--lex') = 0 then |     if CompareStr(parameter, "--lex") = 0 then | ||||||
|       parsed := true; |       parsed := true; | ||||||
|       result^.lex := true |       result^.lex := true | ||||||
|     end; |     end; | ||||||
|     if CompareStr(parameter, '--parse') = 0 then |     if CompareStr(parameter, "--parse") = 0 then | ||||||
|       parsed := true; |       parsed := true; | ||||||
|       result^.parse := true |       result^.parse := true | ||||||
|     end; |     end; | ||||||
|     if CompareStr(parameter, '-o') = 0 then |     if CompareStr(parameter, "-o") = 0 then | ||||||
|       i := i + 1u; |       i := i + 1u; | ||||||
|  |  | ||||||
|       if i = Narg() then |       if i = Narg() then | ||||||
|         WriteString(StdErr, 'Fatal error: expecting a file name following -o.'); |         WriteString(StdErr, "Fatal error: expecting a file name following -o."); | ||||||
|         result := nil |         result := nil | ||||||
|       end; |       end; | ||||||
|       if i < Narg() then |       if i < Narg() then | ||||||
| @@ -57,15 +55,15 @@ begin | |||||||
|       end; |       end; | ||||||
|       parsed := true |       parsed := true | ||||||
|     end; |     end; | ||||||
|     if (parameter[1] <> '-') & (parsed = false) then |     if (parameter[1] <> "-") & (parsed = false) then | ||||||
|       parsed := true; |       parsed := true; | ||||||
|  |  | ||||||
|       if Length(result^.input) > 0 then |       if Length(result^.input) > 0 then | ||||||
|         WriteString(StdErr, 'Fatal error: only one source file can be compiled at once. First given "'); |         WriteString(StdErr, "Fatal error: only one source file can be compiled at once. First given \""); | ||||||
|         WriteString(StdErr, result^.input); |         WriteString(StdErr, result^.input); | ||||||
|         WriteString(StdErr, '", then "'); |         WriteString(StdErr, "\", then \""); | ||||||
|         WriteString(StdErr, parameter); |         WriteString(StdErr, parameter); | ||||||
|         WriteString(StdErr, '".'); |         WriteString(StdErr, "\"."); | ||||||
|         WriteLine(StdErr); |         WriteLine(StdErr); | ||||||
|         result := nil |         result := nil | ||||||
|       end; |       end; | ||||||
| @@ -74,7 +72,7 @@ begin | |||||||
|       end |       end | ||||||
|     end; |     end; | ||||||
|     if parsed = false then |     if parsed = false then | ||||||
|       WriteString(StdErr, 'Fatal error: unknown command line options: '); |       WriteString(StdErr, "Fatal error: unknown command line options: "); | ||||||
|  |  | ||||||
|       WriteString(StdErr, parameter); |       WriteString(StdErr, parameter); | ||||||
|       WriteChar(StdErr, '.'); |       WriteChar(StdErr, '.'); | ||||||
| @@ -86,7 +84,7 @@ begin | |||||||
|     i := i + 1 |     i := i + 1 | ||||||
|   end; |   end; | ||||||
|   if (result <> nil) & (Length(result^.input) = 0) then |   if (result <> nil) & (Length(result^.input) = 0) then | ||||||
|     WriteString(StdErr, 'Fatal error: no input files.'); |     WriteString(StdErr, "Fatal error: no input files."); | ||||||
|     WriteLine(StdErr); |     WriteLine(StdErr); | ||||||
|     result := nil |     result := nil | ||||||
|   end; |   end; | ||||||
|   | |||||||
| @@ -1,74 +0,0 @@ | |||||||
| (* This Source Code Form is subject to the terms of the Mozilla Public License, |  | ||||||
|   v. 2.0. If a copy of the MPL was not distributed with this file, You can |  | ||||||
|   obtain one at https://mozilla.org/MPL/2.0/. *) |  | ||||||
| program; |  | ||||||
|  |  | ||||||
| from FIO import Close, IsNoError, File, OpenToRead, OpenToWrite, StdErr, StdOut, WriteLine, WriteString; |  | ||||||
| from M2RTS import HALT, ExitOnHalt; |  | ||||||
|  |  | ||||||
| from Lexer import Lexer, lexer_destroy, lexer_initialize; |  | ||||||
| from Transpiler import transpile; |  | ||||||
| from CommandLineInterface import CommandLine, parse_command_line; |  | ||||||
| from Parser import AstModule, parse; |  | ||||||
| from Strings import Length; |  | ||||||
|  |  | ||||||
| var |  | ||||||
|   command_line: ^CommandLine; |  | ||||||
|  |  | ||||||
| proc compile_from_stream(); |  | ||||||
| var |  | ||||||
|   lexer: Lexer; |  | ||||||
|   source_input: File; |  | ||||||
|   source_output: File; |  | ||||||
|   ast_module: ^AstModule; |  | ||||||
| begin |  | ||||||
|   source_input := OpenToRead(command_line^.input); |  | ||||||
|  |  | ||||||
|   if IsNoError(source_input) = false then |  | ||||||
|     WriteString(StdErr, 'Fatal error: failed to read the input file "'); |  | ||||||
|     WriteString(StdErr, command_line^.input); |  | ||||||
|     WriteString(StdErr, '".'); |  | ||||||
|     WriteLine(StdErr); |  | ||||||
|  |  | ||||||
|     ExitOnHalt(2) |  | ||||||
|   end; |  | ||||||
|   source_output := nil; |  | ||||||
|  |  | ||||||
|   if Length(command_line^.output) > 0 then |  | ||||||
|     source_output := OpenToWrite(command_line^.output); |  | ||||||
|  |  | ||||||
|     if IsNoError(source_output) = false then |  | ||||||
|       WriteString(StdErr, 'Fatal error: failed to create the output file "'); |  | ||||||
|       WriteString(StdErr, command_line^.output); |  | ||||||
|       WriteString(StdErr, '".'); |  | ||||||
|       WriteLine(StdErr); |  | ||||||
|       |  | ||||||
|       ExitOnHalt(2) |  | ||||||
|     end |  | ||||||
|   end; |  | ||||||
|  |  | ||||||
|   if IsNoError(source_input) then |  | ||||||
|     lexer_initialize(@lexer, source_input); |  | ||||||
|  |  | ||||||
|     ast_module := parse(@lexer); |  | ||||||
|     transpile(ast_module, StdOut, source_output, command_line^.input); |  | ||||||
|  |  | ||||||
|     lexer_destroy(@lexer); |  | ||||||
|  |  | ||||||
|     Close(source_output); |  | ||||||
|     Close(source_input) |  | ||||||
|   end |  | ||||||
| end; |  | ||||||
|  |  | ||||||
| begin |  | ||||||
|   ExitOnHalt(0); |  | ||||||
|   command_line := parse_command_line(); |  | ||||||
|  |  | ||||||
|   if command_line <> nil then |  | ||||||
|     compile_from_stream() |  | ||||||
|   end; |  | ||||||
|   if command_line = nil then |  | ||||||
|     ExitOnHalt(1) |  | ||||||
|   end; |  | ||||||
|   HALT() |  | ||||||
| end. |  | ||||||
| @@ -3,7 +3,7 @@ | |||||||
|   obtain one at https://mozilla.org/MPL/2.0/. *) |   obtain one at https://mozilla.org/MPL/2.0/. *) | ||||||
| module; | module; | ||||||
|  |  | ||||||
| import Common, cstdlib; | import cstdio, cstring, common; | ||||||
|  |  | ||||||
| const | const | ||||||
|   CHUNK_SIZE := 85536; |   CHUNK_SIZE := 85536; | ||||||
| @@ -11,10 +11,10 @@ const | |||||||
| type | type | ||||||
|   (* |   (* | ||||||
|    * Classification table assigns each possible character to a group (class). All |    * Classification table assigns each possible character to a group (class). All | ||||||
|   * characters of the same group a handled equivalently. |    * characters of the same group a handled equivalently. | ||||||
|   * |    * | ||||||
|   * Classification: |    * Classification: | ||||||
|   *) |    *) | ||||||
|   TransitionClass = ( |   TransitionClass = ( | ||||||
|     invalid, |     invalid, | ||||||
|     digit, |     digit, | ||||||
| @@ -293,7 +293,7 @@ begin | |||||||
|   i := 129u; |   i := 129u; | ||||||
|   while i <= 256u do |   while i <= 256u do | ||||||
|     classification[i] := TransitionClass.other; |     classification[i] := TransitionClass.other; | ||||||
|     i := i + 1 |     i := i + 1u | ||||||
|   end |   end | ||||||
| end; | end; | ||||||
|  |  | ||||||
| @@ -410,16 +410,16 @@ begin | |||||||
|   if lexer^.start.iterator^ = '"' then |   if lexer^.start.iterator^ = '"' then | ||||||
|     text_length := lexer^.current.iterator - lexer^.start.iterator + 1; |     text_length := lexer^.current.iterator - lexer^.start.iterator + 1; | ||||||
|  |  | ||||||
|     MemZero(@token^.stringKind, #size(ShortString)); |     memset(@token^.stringKind, 0, #size(ShortString)); | ||||||
|     MemCopy(lexer^.start.iterator, text_length, @token^.stringKind); |     memcpy(@token^.stringKind, lexer^.start.iterator, text_length); | ||||||
|  |  | ||||||
|     token^.kind := LexerKind.character |     token^.kind := LexerKind.character | ||||||
|   end; |   end; | ||||||
|   if lexer^.start.iterator^ = "'" then |   if lexer^.start.iterator^ = "'" then | ||||||
|     text_length := lexer^.current.iterator - lexer^.start.iterator + 1; |     text_length := lexer^.current.iterator - lexer^.start.iterator + 1; | ||||||
|  |  | ||||||
|     MemZero(@token^.stringKind, #size(ShortString)); |     memset(@token^.stringKind, 0, #size(ShortString)); | ||||||
|     MemCopy(lexer^.start.iterator, text_length, @token^.stringKind); |     memcpy(@token^.stringKind, lexer^.start.iterator, text_length); | ||||||
|  |  | ||||||
|     token^.kind := LexerKind.string |     token^.kind := LexerKind.string | ||||||
|   end; |   end; | ||||||
| @@ -432,7 +432,7 @@ begin | |||||||
|   token^.kind := LexerKind.identifier; |   token^.kind := LexerKind.identifier; | ||||||
|  |  | ||||||
|   token^.identifierKind[1] := cast(lexer^.current.iterator - lexer^.start.iterator: Char); |   token^.identifierKind[1] := cast(lexer^.current.iterator - lexer^.start.iterator: Char); | ||||||
|   MemCopy(lexer^.start.iterator, ORD(token^.identifierKind[1]), @token^.identifierKind[2]); |   memcpy(@token^.identifierKind[2], lexer^.start.iterator, ORD(token^.identifierKind[1])); | ||||||
|  |  | ||||||
|   if compare_keyword("program", lexer^.start, lexer^.current.iterator) then |   if compare_keyword("program", lexer^.start, lexer^.current.iterator) then | ||||||
|     token^.kind := LexerKind._program |     token^.kind := LexerKind._program | ||||||
| @@ -590,8 +590,8 @@ begin | |||||||
|   token^.kind := LexerKind.integer; |   token^.kind := LexerKind.integer; | ||||||
|  |  | ||||||
|   integer_length := lexer^.current.iterator - lexer^.start.iterator; |   integer_length := lexer^.current.iterator - lexer^.start.iterator; | ||||||
|   MemZero(@token^.identifierKind, #size(Identifier)); |   memset(@token^.identifierKind, 0, #size(Identifier)); | ||||||
|   MemCopy(lexer^.start.iterator, integer_length, @token^.identifierKind[1]); |   memcpy(@token^.identifierKind[1], lexer^.start.iterator, integer_length); | ||||||
|  |  | ||||||
|   buffer := InitStringCharStar(@token^.identifierKind[1]); |   buffer := InitStringCharStar(@token^.identifierKind[1]); | ||||||
|   token^.integerKind := StringToInteger(buffer, 10, found); |   token^.integerKind := StringToInteger(buffer, 10, found); | ||||||
| @@ -889,7 +889,7 @@ begin | |||||||
|   lexer^.length := 0; |   lexer^.length := 0; | ||||||
|  |  | ||||||
|   lexer^.buffer := malloc(CHUNK_SIZE); |   lexer^.buffer := malloc(CHUNK_SIZE); | ||||||
|   MemZero(lexer^.buffer, CHUNK_SIZE); |   memset(lexer^.buffer, 0, CHUNK_SIZE); | ||||||
|   lexer^.size := CHUNK_SIZE |   lexer^.size := CHUNK_SIZE | ||||||
| end; | end; | ||||||
|  |  | ||||||
|   | |||||||
| @@ -3,11 +3,7 @@ | |||||||
|   obtain one at https://mozilla.org/MPL/2.0/. *) |   obtain one at https://mozilla.org/MPL/2.0/. *) | ||||||
| module; | module; | ||||||
|  |  | ||||||
| import cstdlib; | import cstdlib, common, Lexer; | ||||||
| from MemUtils import MemZero; |  | ||||||
|  |  | ||||||
| from Common import Identifier, ShortString; |  | ||||||
| from Lexer import Lexer, LexerToken, lexer_current, lexer_lex; |  | ||||||
|  |  | ||||||
| type | type | ||||||
|   Parser = record |   Parser = record | ||||||
| @@ -237,7 +233,7 @@ begin | |||||||
|     end |     end | ||||||
|   end; |   end; | ||||||
|   current_field := current_field + 1; |   current_field := current_field + 1; | ||||||
|   MemZero(current_field, #size(AstFieldDeclaration)); |   memset(current_field, 0, #size(AstFieldDeclaration)); | ||||||
|  |  | ||||||
|   return field_declarations |   return field_declarations | ||||||
| end; | end; | ||||||
| @@ -331,7 +327,7 @@ begin | |||||||
|     token := parser_lex(parser^.lexer) |     token := parser_lex(parser^.lexer) | ||||||
|   end; |   end; | ||||||
|   current_case := current_case + 1; |   current_case := current_case + 1; | ||||||
|   MemZero(current_case, #size(Identifier)); |   memset(current_case, 0, #size(Identifier)); | ||||||
|  |  | ||||||
|   return result |   return result | ||||||
| end; | end; | ||||||
| @@ -608,7 +604,7 @@ begin | |||||||
|     token := parser_lex(parser^.lexer) |     token := parser_lex(parser^.lexer) | ||||||
|   end; |   end; | ||||||
|   current_symbol := current_symbol + 1; |   current_symbol := current_symbol + 1; | ||||||
|   MemZero(current_symbol, #size(Identifier)); |   memset(current_symbol, 0, #size(Identifier)); | ||||||
|  |  | ||||||
|   token := parser_lex(parser^.lexer); |   token := parser_lex(parser^.lexer); | ||||||
|  |  | ||||||
|   | |||||||
| @@ -6,7 +6,7 @@ module; | |||||||
| from FIO import File, WriteNBytes, WriteLine, WriteChar, WriteString; | from FIO import File, WriteNBytes, WriteLine, WriteChar, WriteString; | ||||||
| from NumberIO import IntToStr; | from NumberIO import IntToStr; | ||||||
|  |  | ||||||
| from Common import Identifier, ShortString; | import common; | ||||||
| from Parser import AstLiteralKind, AstUnaryOperator, AstBinaryOperator, AstModule, AstExpression, AstLiteral, | from Parser import AstLiteralKind, AstUnaryOperator, AstBinaryOperator, AstModule, AstExpression, AstLiteral, | ||||||
|   AstConstantDeclaration, AstStatement, AstTypedDeclaration, AstCompoundStatement, AstProcedureDeclaration, |   AstConstantDeclaration, AstStatement, AstTypedDeclaration, AstCompoundStatement, AstProcedureDeclaration, | ||||||
|   AstVariableDeclaration, AstImportStatement, AstTypeExpression, AstFieldDeclaration; |   AstVariableDeclaration, AstImportStatement, AstTypeExpression, AstFieldDeclaration; | ||||||
| @@ -26,7 +26,7 @@ begin | |||||||
|   count := 0; |   count := 0; | ||||||
|  |  | ||||||
|   while count < context^.indentation do |   while count < context^.indentation do | ||||||
|     WriteString(context^.output, '  '); |     WriteString(context^.output, "  "); | ||||||
|     count := count + 1u |     count := count + 1u | ||||||
|   end |   end | ||||||
| end; | end; | ||||||
| @@ -43,17 +43,17 @@ var | |||||||
|   written_bytes: Word; |   written_bytes: Word; | ||||||
|   current_symbol: ^Identifier; |   current_symbol: ^Identifier; | ||||||
| begin | begin | ||||||
|   WriteString(context^.output, 'FROM '); |   WriteString(context^.output, "FROM "); | ||||||
|   written_bytes := WriteNBytes(context^.output, ORD(import_statement^.package[1]), @import_statement^.package[2]); |   written_bytes := WriteNBytes(context^.output, ORD(import_statement^.package[1]), @import_statement^.package[2]); | ||||||
|  |  | ||||||
|   WriteString(context^.output, ' IMPORT '); |   WriteString(context^.output, " IMPORT "); | ||||||
|  |  | ||||||
|   current_symbol := import_statement^.symbols; |   current_symbol := import_statement^.symbols; | ||||||
|   written_bytes := WriteNBytes(context^.output, ORD(current_symbol^[1]), @current_symbol^[2]); |   written_bytes := WriteNBytes(context^.output, ORD(current_symbol^[1]), @current_symbol^[2]); | ||||||
|   current_symbol := current_symbol + 1; |   current_symbol := current_symbol + 1; | ||||||
|  |  | ||||||
|   while ORD(current_symbol^[1]) <> 0 do |   while ORD(current_symbol^[1]) <> 0 do | ||||||
|     WriteString(context^.output, ', '); |     WriteString(context^.output, ", "); | ||||||
|     written_bytes := WriteNBytes(context^.output, ORD(current_symbol^[1]), @current_symbol^[2]); |     written_bytes := WriteNBytes(context^.output, ORD(current_symbol^[1]), @current_symbol^[2]); | ||||||
|     current_symbol := current_symbol + 1; |     current_symbol := current_symbol + 1; | ||||||
|   end; |   end; | ||||||
| @@ -76,10 +76,10 @@ var | |||||||
|   buffer: [20]CHAR; |   buffer: [20]CHAR; | ||||||
|   written_bytes: Word; |   written_bytes: Word; | ||||||
| begin | begin | ||||||
|   WriteString(context^.output, '  '); |   WriteString(context^.output, "  "); | ||||||
|   written_bytes := WriteNBytes(context^.output, ORD(declaration^.constant_name[1]), @declaration^.constant_name[2]); |   written_bytes := WriteNBytes(context^.output, ORD(declaration^.constant_name[1]), @declaration^.constant_name[2]); | ||||||
|  |  | ||||||
|   WriteString(context^.output, ' = '); |   WriteString(context^.output, " = "); | ||||||
|  |  | ||||||
|   IntToStr(declaration^.constant_value, 0, buffer); |   IntToStr(declaration^.constant_value, 0, buffer); | ||||||
|   WriteString(context^.output, buffer); |   WriteString(context^.output, buffer); | ||||||
| @@ -92,7 +92,7 @@ var | |||||||
|   current_declaration: ^^AstConstantDeclaration; |   current_declaration: ^^AstConstantDeclaration; | ||||||
| begin | begin | ||||||
|   if declarations^ <> nil then |   if declarations^ <> nil then | ||||||
|     WriteString(context^.output, 'CONST'); |     WriteString(context^.output, "CONST"); | ||||||
|     WriteLine(context^.output); |     WriteLine(context^.output); | ||||||
|  |  | ||||||
|     current_declaration := declarations; |     current_declaration := declarations; | ||||||
| @@ -110,9 +110,9 @@ end; | |||||||
| proc transpile_module(context: ^TranspilerContext, result: ^AstModule); | proc transpile_module(context: ^TranspilerContext, result: ^AstModule); | ||||||
| begin | begin | ||||||
|   if result^.main = false then |   if result^.main = false then | ||||||
|     WriteString(context^.output, 'IMPLEMENTATION ') |     WriteString(context^.output, "IMPLEMENTATION ") | ||||||
|   end; |   end; | ||||||
|   WriteString(context^.output, 'MODULE '); |   WriteString(context^.output, "MODULE "); | ||||||
|  |  | ||||||
|   (* Write the module name and end the line with a semicolon and newline. *) |   (* Write the module name and end the line with a semicolon and newline. *) | ||||||
|   transpile_module_name(context); |   transpile_module_name(context); | ||||||
| @@ -129,10 +129,10 @@ begin | |||||||
|   transpile_procedure_part(context, result^.procedures); |   transpile_procedure_part(context, result^.procedures); | ||||||
|   transpile_statement_part(context, result^.statements); |   transpile_statement_part(context, result^.statements); | ||||||
|  |  | ||||||
|   WriteString(context^.output, 'END '); |   WriteString(context^.output, "END "); | ||||||
|   transpile_module_name(context); |   transpile_module_name(context); | ||||||
|  |  | ||||||
|   WriteChar(context^.output, '.'); |   WriteChar(context^.output, "."); | ||||||
|   WriteLine(context^.output) |   WriteLine(context^.output) | ||||||
| end; | end; | ||||||
|  |  | ||||||
| @@ -144,10 +144,10 @@ begin | |||||||
|   current_field := fields; |   current_field := fields; | ||||||
|  |  | ||||||
|   while ORD(current_field^.field_name[1]) <> 0 do |   while ORD(current_field^.field_name[1]) <> 0 do | ||||||
|     WriteString(context^.output, '    '); |     WriteString(context^.output, "    "); | ||||||
|     written_bytes := WriteNBytes(context^.output, ORD(current_field^.field_name[1]), @current_field^.field_name[2]); |     written_bytes := WriteNBytes(context^.output, ORD(current_field^.field_name[1]), @current_field^.field_name[2]); | ||||||
|  |  | ||||||
|     WriteString(context^.output, ': '); |     WriteString(context^.output, ": "); | ||||||
|     transpile_type_expression(context, current_field^.field_type); |     transpile_type_expression(context, current_field^.field_type); | ||||||
|  |  | ||||||
|     current_field := current_field + 1; |     current_field := current_field + 1; | ||||||
| @@ -161,15 +161,15 @@ end; | |||||||
|  |  | ||||||
| proc transpile_record_type(context: ^TranspilerContext, type_expression: ^AstTypeExpression); | proc transpile_record_type(context: ^TranspilerContext, type_expression: ^AstTypeExpression); | ||||||
| begin | begin | ||||||
|   WriteString(context^.output, 'RECORD'); |   WriteString(context^.output, "RECORD"); | ||||||
|   WriteLine(context^.output); |   WriteLine(context^.output); | ||||||
|   transpile_type_fields(context, type_expression^.fields); |   transpile_type_fields(context, type_expression^.fields); | ||||||
|   WriteString(context^.output, '  END') |   WriteString(context^.output, "  END") | ||||||
| end; | end; | ||||||
|  |  | ||||||
| proc transpile_pointer_type(context: ^TranspilerContext, type_expression: ^AstTypeExpression); | proc transpile_pointer_type(context: ^TranspilerContext, type_expression: ^AstTypeExpression); | ||||||
| begin | begin | ||||||
|   WriteString(context^.output, 'POINTER TO '); |   WriteString(context^.output, "POINTER TO "); | ||||||
|  |  | ||||||
|   transpile_type_expression(context, type_expression^.target) |   transpile_type_expression(context, type_expression^.target) | ||||||
| end; | end; | ||||||
| @@ -178,17 +178,17 @@ proc transpile_array_type(context: ^TranspilerContext, type_expression: ^AstType | |||||||
| var | var | ||||||
|   buffer: [20]CHAR; |   buffer: [20]CHAR; | ||||||
| begin | begin | ||||||
|   WriteString(context^.output, 'ARRAY'); |   WriteString(context^.output, "ARRAY"); | ||||||
|  |  | ||||||
|   if type_expression^.length <> 0 then |   if type_expression^.length <> 0 then | ||||||
|     WriteString(context^.output, '[1..'); |     WriteString(context^.output, "[1.."); | ||||||
|  |  | ||||||
|     IntToStr(type_expression^.length, 0, buffer); |     IntToStr(type_expression^.length, 0, buffer); | ||||||
|     WriteString(context^.output, buffer); |     WriteString(context^.output, buffer); | ||||||
|  |  | ||||||
|     WriteChar(context^.output, ']') |     WriteChar(context^.output, ']') | ||||||
|   end; |   end; | ||||||
|   WriteString(context^.output, ' OF '); |   WriteString(context^.output, " OF "); | ||||||
|  |  | ||||||
|   transpile_type_expression(context, type_expression^.base) |   transpile_type_expression(context, type_expression^.base) | ||||||
| end; | end; | ||||||
| @@ -200,22 +200,22 @@ var | |||||||
| begin | begin | ||||||
|   current_case := type_expression^.cases; |   current_case := type_expression^.cases; | ||||||
|  |  | ||||||
|   WriteString(context^.output, '('); |   WriteString(context^.output, "("); | ||||||
|   WriteLine(context^.output); |   WriteLine(context^.output); | ||||||
|   WriteString(context^.output, '    '); |   WriteString(context^.output, "    "); | ||||||
|   written_bytes := WriteNBytes(context^.output, ORD(current_case^[1]), @current_case^[2]); |   written_bytes := WriteNBytes(context^.output, ORD(current_case^[1]), @current_case^[2]); | ||||||
|   current_case := current_case + 1; |   current_case := current_case + 1; | ||||||
|  |  | ||||||
|   while ORD(current_case^[1]) <> 0 do |   while ORD(current_case^[1]) <> 0 do | ||||||
|     WriteChar(context^.output, ','); |     WriteChar(context^.output, ','); | ||||||
|     WriteLine(context^.output); |     WriteLine(context^.output); | ||||||
|     WriteString(context^.output, '    '); |     WriteString(context^.output, "    "); | ||||||
|     written_bytes := WriteNBytes(context^.output, ORD(current_case^[1]), @current_case^[2]); |     written_bytes := WriteNBytes(context^.output, ORD(current_case^[1]), @current_case^[2]); | ||||||
|  |  | ||||||
|     current_case := current_case + 1 |     current_case := current_case + 1 | ||||||
|   end; |   end; | ||||||
|   WriteLine(context^.output); |   WriteLine(context^.output); | ||||||
|   WriteString(context^.output, '  )') |   WriteString(context^.output, "  )") | ||||||
| end; | end; | ||||||
|  |  | ||||||
| proc transpile_named_type(context: ^TranspilerContext, type_expression: ^AstTypeExpression); | proc transpile_named_type(context: ^TranspilerContext, type_expression: ^AstTypeExpression); | ||||||
| @@ -231,7 +231,7 @@ var | |||||||
|   current_parameter: ^^AstTypeExpression; |   current_parameter: ^^AstTypeExpression; | ||||||
|   parameter_count: Word; |   parameter_count: Word; | ||||||
| begin | begin | ||||||
|   WriteString(context^.output, 'PROCEDURE('); |   WriteString(context^.output, "PROCEDURE("); | ||||||
|   current_parameter := type_expression^.parameters; |   current_parameter := type_expression^.parameters; | ||||||
|  |  | ||||||
|   while current_parameter^ <> nil do |   while current_parameter^ <> nil do | ||||||
| @@ -240,7 +240,7 @@ begin | |||||||
|     current_parameter := current_parameter + 1; |     current_parameter := current_parameter + 1; | ||||||
|  |  | ||||||
|     if current_parameter^ <> nil then |     if current_parameter^ <> nil then | ||||||
|       WriteString(context^.output, ', ') |       WriteString(context^.output, ", ") | ||||||
|     end |     end | ||||||
|   end; |   end; | ||||||
|   WriteChar(context^.output, ')') |   WriteChar(context^.output, ')') | ||||||
| @@ -272,10 +272,10 @@ proc transpile_type_declaration(context: ^TranspilerContext, declaration: ^AstTy | |||||||
| var | var | ||||||
|   written_bytes: Word; |   written_bytes: Word; | ||||||
| begin | begin | ||||||
|   WriteString(context^.output, '  '); |   WriteString(context^.output, "  "); | ||||||
|  |  | ||||||
|   written_bytes := WriteNBytes(context^.output, ORD(declaration^.identifier[1]), @declaration^.identifier[2]); |   written_bytes := WriteNBytes(context^.output, ORD(declaration^.identifier[1]), @declaration^.identifier[2]); | ||||||
|   WriteString(context^.output, ' = '); |   WriteString(context^.output, " = "); | ||||||
|  |  | ||||||
|   transpile_type_expression(context, declaration^.type_expression); |   transpile_type_expression(context, declaration^.type_expression); | ||||||
|   write_semicolon(context^.output) |   write_semicolon(context^.output) | ||||||
| @@ -286,7 +286,7 @@ var | |||||||
|   current_declaration: ^^AstTypedDeclaration; |   current_declaration: ^^AstTypedDeclaration; | ||||||
| begin | begin | ||||||
|   if declarations^ <> nil then |   if declarations^ <> nil then | ||||||
|     WriteString(context^.output, 'TYPE'); |     WriteString(context^.output, "TYPE"); | ||||||
|     WriteLine(context^.output); |     WriteLine(context^.output); | ||||||
|  |  | ||||||
|     current_declaration := declarations; |     current_declaration := declarations; | ||||||
| @@ -303,10 +303,10 @@ proc transpile_variable_declaration(context: ^TranspilerContext, declaration: ^A | |||||||
| var | var | ||||||
|   written_bytes: Word; |   written_bytes: Word; | ||||||
| begin | begin | ||||||
|   WriteString(context^.output, '  '); |   WriteString(context^.output, "  "); | ||||||
|   written_bytes := WriteNBytes(context^.output, ORD(declaration^.variable_name[1]), @declaration^.variable_name[2]); |   written_bytes := WriteNBytes(context^.output, ORD(declaration^.variable_name[1]), @declaration^.variable_name[2]); | ||||||
|  |  | ||||||
|   WriteString(context^.output, ': '); |   WriteString(context^.output, ": "); | ||||||
|  |  | ||||||
|   transpile_type_expression(context, declaration^.variable_type); |   transpile_type_expression(context, declaration^.variable_type); | ||||||
|   write_semicolon(context^.output) |   write_semicolon(context^.output) | ||||||
| @@ -317,7 +317,7 @@ var | |||||||
|   current_declaration: ^^AstVariableDeclaration; |   current_declaration: ^^AstVariableDeclaration; | ||||||
| begin | begin | ||||||
|   if declarations^ <> nil then |   if declarations^ <> nil then | ||||||
|     WriteString(context^.output, 'VAR'); |     WriteString(context^.output, "VAR"); | ||||||
|     WriteLine(context^.output); |     WriteLine(context^.output); | ||||||
|  |  | ||||||
|     current_declaration := declarations; |     current_declaration := declarations; | ||||||
| @@ -338,7 +338,7 @@ var | |||||||
|   parameter_index: Word; |   parameter_index: Word; | ||||||
|   current_parameter: ^AstTypedDeclaration; |   current_parameter: ^AstTypedDeclaration; | ||||||
| begin | begin | ||||||
|   WriteString(context^.output, 'PROCEDURE '); |   WriteString(context^.output, "PROCEDURE "); | ||||||
|   written_bytes := WriteNBytes(context^.output, ORD(declaration^.name[1]), @declaration^.name[2]); |   written_bytes := WriteNBytes(context^.output, ORD(declaration^.name[1]), @declaration^.name[2]); | ||||||
|   WriteChar(context^.output, '('); |   WriteChar(context^.output, '('); | ||||||
|  |  | ||||||
| @@ -347,22 +347,22 @@ begin | |||||||
|  |  | ||||||
|   while parameter_index < declaration^.parameter_count do |   while parameter_index < declaration^.parameter_count do | ||||||
|     written_bytes := WriteNBytes(context^.output, ORD(current_parameter^.identifier[1]), @current_parameter^.identifier[2]); |     written_bytes := WriteNBytes(context^.output, ORD(current_parameter^.identifier[1]), @current_parameter^.identifier[2]); | ||||||
|     WriteString(context^.output, ': '); |     WriteString(context^.output, ": "); | ||||||
|     transpile_type_expression(context, current_parameter^.type_expression); |     transpile_type_expression(context, current_parameter^.type_expression); | ||||||
|  |  | ||||||
|     parameter_index := parameter_index + 1u; |     parameter_index := parameter_index + 1u; | ||||||
|     current_parameter := current_parameter + 1; |     current_parameter := current_parameter + 1; | ||||||
|  |  | ||||||
|     if parameter_index <> declaration^.parameter_count then |     if parameter_index <> declaration^.parameter_count then | ||||||
|       WriteString(context^.output, '; ') |       WriteString(context^.output, "; ") | ||||||
|     end |     end | ||||||
|   end; |   end; | ||||||
|  |  | ||||||
|   WriteString(context^.output, ')'); |   WriteString(context^.output, ")"); | ||||||
|  |  | ||||||
|   (* Check for the return type and write it. *) |   (* Check for the return type and write it. *) | ||||||
|   if declaration^.return_type <> nil then |   if declaration^.return_type <> nil then | ||||||
|     WriteString(context^.output, ': '); |     WriteString(context^.output, ": "); | ||||||
|     transpile_type_expression(context, declaration^.return_type) |     transpile_type_expression(context, declaration^.return_type) | ||||||
|   end; |   end; | ||||||
|   write_semicolon(context^.output) |   write_semicolon(context^.output) | ||||||
| @@ -388,10 +388,10 @@ begin | |||||||
| 	| AstBinaryOperator.not_equals: WriteChar(context^.output, '#') | 	| AstBinaryOperator.not_equals: WriteChar(context^.output, '#') | ||||||
| 	| AstBinaryOperator.less: WriteChar(context^.output, '<') | 	| AstBinaryOperator.less: WriteChar(context^.output, '<') | ||||||
| 	| AstBinaryOperator.greater: WriteChar(context^.output, '>') | 	| AstBinaryOperator.greater: WriteChar(context^.output, '>') | ||||||
|   	| AstBinaryOperator.less_equal: WriteString(context^.output, '<=') |   	| AstBinaryOperator.less_equal: WriteString(context^.output, "<=") | ||||||
|   	| AstBinaryOperator.greater_equal: WriteString(context^.output, '>=') |   	| AstBinaryOperator.greater_equal: WriteString(context^.output, ">=") | ||||||
|   	| AstBinaryOperator.disjunction: WriteString(context^.output, 'OR') |   	| AstBinaryOperator.disjunction: WriteString(context^.output, "OR") | ||||||
| 	| AstBinaryOperatorConjunction: WriteString(context^.output, 'AND') | 	| AstBinaryOperatorConjunction: WriteString(context^.output, "AND") | ||||||
|   end |   end | ||||||
| end; | end; | ||||||
|  |  | ||||||
| @@ -414,13 +414,13 @@ begin | |||||||
|       WriteString(context^.output, literal^.string) |       WriteString(context^.output, literal^.string) | ||||||
|     end; |     end; | ||||||
|     if literal^.kind = AstLiteralKind.null then |     if literal^.kind = AstLiteralKind.null then | ||||||
|       WriteString(context^.output, 'NIL') |       WriteString(context^.output, "NIL") | ||||||
|     end; |     end; | ||||||
|     if (literal^.kind = AstLiteralKind.boolean) & literal^.boolean then |     if (literal^.kind = AstLiteralKind.boolean) & literal^.boolean then | ||||||
|       WriteString(context^.output, 'TRUE') |       WriteString(context^.output, "TRUE") | ||||||
|     end; |     end; | ||||||
|     if (literal^.kind = AstLiteralKind.boolean) & (literal^.boolean = false) then |     if (literal^.kind = AstLiteralKind.boolean) & (literal^.boolean = false) then | ||||||
|       WriteString(context^.output, 'FALSE') |       WriteString(context^.output, "FALSE") | ||||||
|     end |     end | ||||||
|   end; |   end; | ||||||
|   if expression^.kind = astExpressionKindIdentifier then |   if expression^.kind = astExpressionKindIdentifier then | ||||||
| @@ -466,7 +466,7 @@ begin | |||||||
|       current_argument := current_argument + 1; |       current_argument := current_argument + 1; | ||||||
|  |  | ||||||
|       while argument_index < expression^.argument_count do |       while argument_index < expression^.argument_count do | ||||||
|         WriteString(context^.output, ', '); |         WriteString(context^.output, ", "); | ||||||
|  |  | ||||||
|         transpile_expression(context, current_argument^); |         transpile_expression(context, current_argument^); | ||||||
|  |  | ||||||
| @@ -480,44 +480,44 @@ end; | |||||||
|  |  | ||||||
| proc transpile_if_statement(context: ^TranspilerContext, statement: ^AstStatement); | proc transpile_if_statement(context: ^TranspilerContext, statement: ^AstStatement); | ||||||
| begin | begin | ||||||
|   WriteString(context^.output, 'IF '); |   WriteString(context^.output, "IF "); | ||||||
|   transpile_expression(context, statement^.if_condition); |   transpile_expression(context, statement^.if_condition); | ||||||
|  |  | ||||||
|   WriteString(context^.output, ' THEN'); |   WriteString(context^.output, " THEN"); | ||||||
|   WriteLine(context^.output); |   WriteLine(context^.output); | ||||||
|   context^.indentation := context^.indentation + 1u; |   context^.indentation := context^.indentation + 1u; | ||||||
|  |  | ||||||
|   transpile_compound_statement(context, statement^.if_branch); |   transpile_compound_statement(context, statement^.if_branch); | ||||||
|   context^.indentation := context^.indentation - 1u; |   context^.indentation := context^.indentation - 1u; | ||||||
|   indent(context); |   indent(context); | ||||||
|   WriteString(context^.output, 'END') |   WriteString(context^.output, "END") | ||||||
| end; | end; | ||||||
|  |  | ||||||
| proc transpile_while_statement(context: ^TranspilerContext, statement: ^AstStatement); | proc transpile_while_statement(context: ^TranspilerContext, statement: ^AstStatement); | ||||||
| begin | begin | ||||||
|   WriteString(context^.output, 'WHILE '); |   WriteString(context^.output, "WHILE "); | ||||||
|   transpile_expression(context, statement^.while_condition); |   transpile_expression(context, statement^.while_condition); | ||||||
|  |  | ||||||
|   WriteString(context^.output, ' DO'); |   WriteString(context^.output, " DO"); | ||||||
|   WriteLine(context^.output); |   WriteLine(context^.output); | ||||||
|   context^.indentation := context^.indentation + 1u; |   context^.indentation := context^.indentation + 1u; | ||||||
|  |  | ||||||
|   transpile_compound_statement(context, statement^.while_body); |   transpile_compound_statement(context, statement^.while_body); | ||||||
|   context^.indentation := context^.indentation - 1u; |   context^.indentation := context^.indentation - 1u; | ||||||
|   indent(context); |   indent(context); | ||||||
|   WriteString(context^.output, 'END') |   WriteString(context^.output, "END") | ||||||
| end; | end; | ||||||
|  |  | ||||||
| proc transpile_assignment_statement(context: ^TranspilerContext, statement: ^AstStatement); | proc transpile_assignment_statement(context: ^TranspilerContext, statement: ^AstStatement); | ||||||
| begin | begin | ||||||
|   transpile_expression(context, statement^.assignee); |   transpile_expression(context, statement^.assignee); | ||||||
|   WriteString(context^.output, ' := '); |   WriteString(context^.output, " := "); | ||||||
|   transpile_expression(context, statement^.assignment) |   transpile_expression(context, statement^.assignment) | ||||||
| end; | end; | ||||||
|  |  | ||||||
| proc transpile_return_statement(context: ^TranspilerContext, statement: ^AstStatement); | proc transpile_return_statement(context: ^TranspilerContext, statement: ^AstStatement); | ||||||
| begin | begin | ||||||
|   WriteString(context^.output, 'RETURN '); |   WriteString(context^.output, "RETURN "); | ||||||
|  |  | ||||||
|   transpile_expression(context, statement^.returned) |   transpile_expression(context, statement^.returned) | ||||||
| end; | end; | ||||||
| @@ -567,7 +567,7 @@ end; | |||||||
| proc transpile_statement_part(context: ^TranspilerContext, compound: AstCompoundStatement); | proc transpile_statement_part(context: ^TranspilerContext, compound: AstCompoundStatement); | ||||||
| begin | begin | ||||||
|   if compound.count > 0 then |   if compound.count > 0 then | ||||||
|     WriteString(context^.output, 'BEGIN'); |     WriteString(context^.output, "BEGIN"); | ||||||
|     WriteLine(context^.output); |     WriteLine(context^.output); | ||||||
|  |  | ||||||
|     context^.indentation := context^.indentation + 1u; |     context^.indentation := context^.indentation + 1u; | ||||||
| @@ -586,7 +586,7 @@ begin | |||||||
|   transpile_variable_part(context, declaration^.variables, false); |   transpile_variable_part(context, declaration^.variables, false); | ||||||
|   transpile_statement_part(context, declaration^.statements); |   transpile_statement_part(context, declaration^.statements); | ||||||
|  |  | ||||||
|   WriteString(context^.output, 'END '); |   WriteString(context^.output, "END "); | ||||||
|   written_bytes := WriteNBytes(context^.output, ORD(declaration^.name[1]), @declaration^.name[2]); |   written_bytes := WriteNBytes(context^.output, ORD(declaration^.name[1]), @declaration^.name[2]); | ||||||
|  |  | ||||||
|   write_semicolon(context^.output) |   write_semicolon(context^.output) | ||||||
|   | |||||||
							
								
								
									
										11
									
								
								source/cctype.elna
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										11
									
								
								source/cctype.elna
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,11 @@ | |||||||
|  | (* This Source Code Form is subject to the terms of the Mozilla Public License, | ||||||
|  |   v. 2.0. If a copy of the MPL was not distributed with this file, You can | ||||||
|  |   obtain one at https://mozilla.org/MPL/2.0/. *) | ||||||
|  | module; | ||||||
|  |  | ||||||
|  | proc isdigit(c: Int ) -> Int; extern; | ||||||
|  | proc isalnum(c: Int) -> Int; extern; | ||||||
|  | proc isalpha(c: Int) -> Int; extern; | ||||||
|  | proc isspace(c: Int) -> Int; extern; | ||||||
|  |  | ||||||
|  | end. | ||||||
| @@ -10,6 +10,5 @@ type | |||||||
|     line: Word; |     line: Word; | ||||||
|     column: Word |     column: Word | ||||||
|   end; |   end; | ||||||
|   FILE* = record end; |  | ||||||
| 
 | 
 | ||||||
| end. | end. | ||||||
							
								
								
									
										23
									
								
								source/cstdio.elna
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										23
									
								
								source/cstdio.elna
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,23 @@ | |||||||
|  | (* This Source Code Form is subject to the terms of the Mozilla Public License, | ||||||
|  |   v. 2.0. If a copy of the MPL was not distributed with this file, You can | ||||||
|  |   obtain one at https://mozilla.org/MPL/2.0/. *) | ||||||
|  | module; | ||||||
|  |  | ||||||
|  | type | ||||||
|  |   FILE* = record end; | ||||||
|  |  | ||||||
|  | proc fopen(pathname: ^Char, mode: ^Char) -> ^FILE; extern; | ||||||
|  | proc fclose(stream: ^FILE) -> Int; extern; | ||||||
|  | proc fseek(stream: ^FILE, off: Int, whence: Int) -> Int; extern; | ||||||
|  | proc rewind(stream: ^FILE); extern; | ||||||
|  | proc ftell(stream: ^FILE) -> Int; extern; | ||||||
|  | proc fflush(stream: ^FILE) -> Int; extern; | ||||||
|  |  | ||||||
|  | proc fread(ptr: Pointer, size: Word, nmemb: Word, stream: ^FILE) -> Word; extern; | ||||||
|  |  | ||||||
|  | proc perror(s: ^Char); extern; | ||||||
|  |  | ||||||
|  | proc puts(s: ^Char) -> Int; extern; | ||||||
|  | proc putchar(c: Int) -> Int; extern; | ||||||
|  |  | ||||||
|  | end. | ||||||
							
								
								
									
										13
									
								
								source/cstdlib.elna
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										13
									
								
								source/cstdlib.elna
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,13 @@ | |||||||
|  | (* This Source Code Form is subject to the terms of the Mozilla Public License, | ||||||
|  |   v. 2.0. If a copy of the MPL was not distributed with this file, You can | ||||||
|  |   obtain one at https://mozilla.org/MPL/2.0/. *) | ||||||
|  | module; | ||||||
|  |  | ||||||
|  | proc malloc(size: Word) -> Pointer; extern; | ||||||
|  | proc free(ptr: Pointer); extern; | ||||||
|  | proc calloc(nmemb: Word, size: Word) -> Pointer; extern; | ||||||
|  | proc realloc(ptr: Pointer, size: Word) -> Pointer; extern; | ||||||
|  |  | ||||||
|  | proc exit(code: Int) -> !; extern; | ||||||
|  |  | ||||||
|  | end. | ||||||
							
								
								
									
										15
									
								
								source/cstring.elna
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										15
									
								
								source/cstring.elna
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,15 @@ | |||||||
|  | (* This Source Code Form is subject to the terms of the Mozilla Public License, | ||||||
|  |   v. 2.0. If a copy of the MPL was not distributed with this file, You can | ||||||
|  |   obtain one at https://mozilla.org/MPL/2.0/. *) | ||||||
|  | module; | ||||||
|  |  | ||||||
|  | proc memset(ptr: Pointer, c: Int, n: Int) -> ^Char; extern; | ||||||
|  | proc memcpy(dst: Pointer, src: Pointer, n: Word); extern; | ||||||
|  |  | ||||||
|  | proc strcmp(s1: ^Char, s2: ^Char) -> Int; extern; | ||||||
|  | proc strncmp(s1: ^Char, s2: ^Char, n: Word) -> Int; extern; | ||||||
|  | proc strncpy(dst: ^Char, src: ^Char, dsize: Word) -> ^Char; extern; | ||||||
|  | proc strcpy(dst: ^Char, src: ^Char) -> ^Char; extern; | ||||||
|  | proc strlen(ptr: ^Char) -> Word; extern; | ||||||
|  |  | ||||||
|  | end. | ||||||
| @@ -3,7 +3,7 @@ | |||||||
|   obtain one at https://mozilla.org/MPL/2.0/. *) |   obtain one at https://mozilla.org/MPL/2.0/. *) | ||||||
| program; | program; | ||||||
|  |  | ||||||
| import Common, Lexer; | import cstdlib, cstring, cstdio, cctype, common, Lexer; | ||||||
|  |  | ||||||
| const | const | ||||||
|   SEEK_SET* := 0; |   SEEK_SET* := 0; | ||||||
| @@ -127,30 +127,8 @@ type | |||||||
|   External procedures. |   External procedures. | ||||||
| *) | *) | ||||||
|  |  | ||||||
| proc fopen(pathname: ^Char, mode: ^Char) -> ^FILE; extern; |  | ||||||
| proc fclose(stream: ^FILE) -> Int; extern; |  | ||||||
| proc fseek(stream: ^FILE, off: Int, whence: Int) -> Int; extern; |  | ||||||
| proc rewind(stream: ^FILE); extern; |  | ||||||
| proc ftell(stream: ^FILE) -> Int; extern; |  | ||||||
| proc fread(ptr: Pointer, size: Word, nmemb: Word, stream: ^FILE) -> Word; extern; |  | ||||||
| proc write(fd: Int, buf: Pointer, Word: Int) -> Int; extern; | proc write(fd: Int, buf: Pointer, Word: Int) -> Int; extern; | ||||||
|  |  | ||||||
| proc malloc(size: Word) -> Pointer; extern; |  | ||||||
| proc free(ptr: Pointer); extern; |  | ||||||
| proc calloc(nmemb: Word, size: Word) -> Pointer; extern; |  | ||||||
| proc realloc(ptr: Pointer, size: Word) -> Pointer; extern; |  | ||||||
|  |  | ||||||
| proc memset(ptr: ^Char, c: Int, n: Int) -> ^Char; extern; |  | ||||||
|  |  | ||||||
| proc strcmp(s1: ^Char, s2: ^Char) -> Int; extern; |  | ||||||
| proc strncmp(s1: ^Char, s2: ^Char, n: Word) -> Int; extern; |  | ||||||
| proc strncpy(dst: ^Char, src: ^Char, dsize: Word) -> ^Char; extern; |  | ||||||
| proc strcpy(dst: ^Char, src: ^Char) -> ^Char; extern; |  | ||||||
| proc strlen(ptr: ^Char) -> Word; extern; |  | ||||||
|  |  | ||||||
| proc perror(s: ^Char); extern; |  | ||||||
| proc exit(code: Int) -> !; extern; |  | ||||||
|  |  | ||||||
| (* | (* | ||||||
|   Standard procedures. |   Standard procedures. | ||||||
| *) | *) | ||||||
| @@ -161,12 +139,12 @@ end; | |||||||
|  |  | ||||||
| proc write_s(value: String); | proc write_s(value: String); | ||||||
| begin | begin | ||||||
|   write(0, cast(value.ptr: Pointer), cast(value.length: Int)) |   write(1, cast(value.ptr: Pointer), cast(value.length: Int)) | ||||||
| end; | end; | ||||||
|  |  | ||||||
| proc write_z(value: ^Char); | proc write_z(value: ^Char); | ||||||
| begin | begin | ||||||
|   write(0, cast(value: Pointer), cast(strlen(value): Int)) |   write(1, cast(value: Pointer), cast(strlen(value): Int)) | ||||||
| end; | end; | ||||||
|  |  | ||||||
| proc write_b(value: Bool); | proc write_b(value: Bool); | ||||||
| @@ -180,7 +158,8 @@ end; | |||||||
|  |  | ||||||
| proc write_c(value: Char); | proc write_c(value: Char); | ||||||
| begin | begin | ||||||
|   write(0, cast(@value: Pointer), 1) |   putchar(cast(value: Int)); | ||||||
|  |   fflush(nil) | ||||||
| end; | end; | ||||||
|  |  | ||||||
| proc write_i(value: Int); | proc write_i(value: Int); | ||||||
| @@ -212,22 +191,6 @@ begin | |||||||
|   write_i(cast(value: Int)) |   write_i(cast(value: Int)) | ||||||
| end; | end; | ||||||
|  |  | ||||||
| proc is_digit(c: Char) -> Bool; |  | ||||||
|   return cast(c: Int) >= cast('0': Int) & cast(c: Int) <= cast('9': Int) |  | ||||||
| end; |  | ||||||
|  |  | ||||||
| proc is_alpha(c: Char) -> Bool; |  | ||||||
|   return cast(c: Int) >= cast('A': Int) & cast(c: Int) <= cast('z': Int) |  | ||||||
| end; |  | ||||||
|  |  | ||||||
| proc is_alnum(c: Char) -> Bool; |  | ||||||
|   return is_digit(c) or is_alpha(c) |  | ||||||
| end; |  | ||||||
|  |  | ||||||
| proc is_space(c: Char) -> Bool; |  | ||||||
|   return c = ' ' or c = '\n' or c = '\t' |  | ||||||
| end; |  | ||||||
|  |  | ||||||
| proc substring(string: String, start: Word, count: Word) -> String; | proc substring(string: String, start: Word, count: Word) -> String; | ||||||
|   return String(string.ptr + start, count) |   return String(string.ptr + start, count) | ||||||
| end; | end; | ||||||
| @@ -412,7 +375,7 @@ proc lexer_spaces(source_code: ^SourceCode); | |||||||
| var | var | ||||||
|   current: Char; |   current: Char; | ||||||
| begin | begin | ||||||
|   while ~source_code_empty(source_code) & is_space(source_code_head(source_code^)) do |   while ~source_code_empty(source_code) & isspace(cast(source_code_head(source_code^): Int)) <> 0 do | ||||||
|     current := source_code_head(source_code^); |     current := source_code_head(source_code^); | ||||||
|  |  | ||||||
|     if current = '\n' then |     if current = '\n' then | ||||||
| @@ -424,7 +387,7 @@ end; | |||||||
|  |  | ||||||
| (* Checker whether the character is allowed in an identificator. *) | (* Checker whether the character is allowed in an identificator. *) | ||||||
| proc lexer_is_ident(char: Char) -> Bool; | proc lexer_is_ident(char: Char) -> Bool; | ||||||
|   return is_alnum(char) or char = '_' |   return isalnum(cast(char: Int)) <> 0 or char = '_' | ||||||
| end; | end; | ||||||
|  |  | ||||||
| proc lexer_identifier(source_code: ^SourceCode, token_content: ^StringBuffer); | proc lexer_identifier(source_code: ^SourceCode, token_content: ^StringBuffer); | ||||||
| @@ -511,7 +474,7 @@ proc lexer_number(source_code: ^SourceCode, token_content: ^Int); | |||||||
| begin | begin | ||||||
|   token_content^ := 0; |   token_content^ := 0; | ||||||
|  |  | ||||||
|   while ~source_code_empty(source_code) & is_digit(source_code_head(source_code^)) do |   while ~source_code_empty(source_code) & isdigit(cast(source_code_head(source_code^): Int)) <> 0 do | ||||||
|     token_content^ := token_content^ * 10 + (cast(source_code_head(source_code^): Int) - cast('0': Int)); |     token_content^ := token_content^ * 10 + (cast(source_code_head(source_code^): Int) - cast('0': Int)); | ||||||
|  |  | ||||||
|     source_code_advance(source_code) |     source_code_advance(source_code) | ||||||
| @@ -607,7 +570,7 @@ begin | |||||||
|  |  | ||||||
|   first_char := source_code_head(source_code); |   first_char := source_code_head(source_code); | ||||||
|  |  | ||||||
|   if is_alpha(first_char) or first_char = '_' then |   if isalpha(cast(first_char: Int)) <> 0 or first_char = '_' then | ||||||
|     lexer_identifier(@source_code, token_buffer); |     lexer_identifier(@source_code, token_buffer); | ||||||
|     current_token := lexer_categorize(string_buffer_clear(token_buffer)) |     current_token := lexer_categorize(string_buffer_clear(token_buffer)) | ||||||
|   elsif first_char = '#' then |   elsif first_char = '#' then | ||||||
| @@ -616,7 +579,7 @@ begin | |||||||
|  |  | ||||||
|     current_token.kind := TokenKind.trait; |     current_token.kind := TokenKind.trait; | ||||||
|     current_token.value.string := string_dup(string_buffer_clear(token_buffer)) |     current_token.value.string := string_dup(string_buffer_clear(token_buffer)) | ||||||
|   elsif is_digit(first_char) then |   elsif isdigit(cast(first_char: Int)) <> 0 then | ||||||
|     lexer_number(@source_code, @current_token.value.int_value); |     lexer_number(@source_code, @current_token.value.int_value); | ||||||
|  |  | ||||||
|     if source_code_expect(@source_code, 'u') then |     if source_code_expect(@source_code, 'u') then | ||||||
|   | |||||||
		Reference in New Issue
	
	Block a user