Add an empty cstdlib.elna source file

This commit is contained in:
2025-08-10 23:43:09 +03:00
parent 87058adcb3
commit 560689c092
11 changed files with 146 additions and 204 deletions

View File

@@ -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;

View File

@@ -10,6 +10,5 @@ type
line: Word; line: Word;
column: Word column: Word
end; end;
FILE* = record end;
end. end.

View File

@@ -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.

View File

@@ -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, Common;
const const
CHUNK_SIZE := 85536; CHUNK_SIZE := 85536;
@@ -410,7 +410,7 @@ 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); MemCopy(lexer^.start.iterator, text_length, @token^.stringKind);
token^.kind := LexerKind.character token^.kind := LexerKind.character
@@ -418,7 +418,7 @@ 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); MemCopy(lexer^.start.iterator, text_length, @token^.stringKind);
token^.kind := LexerKind.string token^.kind := LexerKind.string
@@ -590,7 +590,7 @@ 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]); MemCopy(lexer^.start.iterator, integer_length, @token^.identifierKind[1]);
buffer := InitStringCharStar(@token^.identifierKind[1]); buffer := InitStringCharStar(@token^.identifierKind[1]);
@@ -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;

View File

@@ -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);

View File

@@ -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
View 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.

23
source/cstdio.elna Normal file
View 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
View 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.

13
source/cstring.elna Normal file
View 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 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;
end.

View File

@@ -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