Trace the source code position in the lexer
This commit is contained in:
@ -1,53 +1,37 @@
|
||||
IMPLEMENTATION MODULE Transpiler;
|
||||
|
||||
FROM FIO IMPORT WriteNBytes, WriteLine, WriteChar, WriteString;
|
||||
FROM SYSTEM IMPORT ADR, ADDRESS, TSIZE;
|
||||
FROM SYSTEM IMPORT ADR, TSIZE;
|
||||
|
||||
FROM NumberIO IMPORT IntToStr;
|
||||
FROM Storage IMPORT ALLOCATE, REALLOCATE;
|
||||
FROM MemUtils IMPORT MemCopy, MemZero;
|
||||
|
||||
FROM Common IMPORT Identifier, PIdentifier, ShortString;
|
||||
FROM Lexer IMPORT Lexer, LexerToken, lexer_current, lexer_lex, LexerKind;
|
||||
FROM Parser IMPORT AstTypeExpressionKind, AstExpressionKind, AstLiteralKind, AstUnaryOperator, AstBinaryOperator,
|
||||
AstModule, PAstModule, AstExpression, PPAstExpression, PAstExpression, PAstLiteral, PPAstProcedureDeclaration,
|
||||
PAstModule, PPAstExpression, PAstExpression, PAstLiteral, PPAstProcedureDeclaration,
|
||||
PAstConstantDeclaration, PPAstConstantDeclaration, PPAstStatement, PAstStatement, AstStatementKind,
|
||||
AstTypedDeclaration, PAstTypedDeclaration, PPAstTypedDeclaration, AstCompoundStatement, PAstProcedureDeclaration,
|
||||
PAstVariableDeclaration, PPAstVariableDeclaration, PAstImportStatement, PPAstImportStatement,
|
||||
PAstTypeExpression, PPAstTypeExpression, AstFieldDeclaration, PAstFieldDeclaration;
|
||||
|
||||
(* Calls lexer_lex() but skips the comments. *)
|
||||
PROCEDURE transpiler_lex(lexer: PLexer): LexerToken;
|
||||
PROCEDURE indent(context: PTranspilerContext);
|
||||
VAR
|
||||
result: LexerToken;
|
||||
count: CARDINAL;
|
||||
BEGIN
|
||||
result := lexer_lex(lexer);
|
||||
count := 0;
|
||||
|
||||
WHILE result.kind = lexerKindComment DO
|
||||
result := lexer_lex(lexer)
|
||||
END;
|
||||
|
||||
RETURN result
|
||||
END transpiler_lex;
|
||||
WHILE count < context^.indentation DO
|
||||
WriteString(context^.output, ' ');
|
||||
INC(count)
|
||||
END
|
||||
END indent;
|
||||
(* Write a semicolon followed by a newline. *)
|
||||
PROCEDURE write_semicolon(output: File);
|
||||
BEGIN
|
||||
WriteChar(output, ';');
|
||||
WriteLine(output)
|
||||
END write_semicolon;
|
||||
PROCEDURE write_current(lexer: PLexer; output: File);
|
||||
VAR
|
||||
written_bytes: CARDINAL;
|
||||
count: CARDINAL;
|
||||
BEGIN
|
||||
count := lexer^.current;
|
||||
DEC(count, lexer^.start);
|
||||
|
||||
written_bytes := WriteNBytes(output, count, lexer^.start)
|
||||
END write_current;
|
||||
PROCEDURE transpile_import_statement(context: PTranspilerContext; import_statement: PAstImportStatement);
|
||||
VAR
|
||||
token: LexerToken;
|
||||
written_bytes: CARDINAL;
|
||||
current_symbol: PIdentifier;
|
||||
BEGIN
|
||||
@ -92,7 +76,7 @@ BEGIN
|
||||
|
||||
write_semicolon(context^.output)
|
||||
END transpile_constant_declaration;
|
||||
PROCEDURE transpile_constant_part(context: PTranspilerContext; declarations: PPAstConstantDeclaration);
|
||||
PROCEDURE transpile_constant_part(context: PTranspilerContext; declarations: PPAstConstantDeclaration; extra_newline: BOOLEAN);
|
||||
VAR
|
||||
current_declaration: PPAstConstantDeclaration;
|
||||
BEGIN
|
||||
@ -106,12 +90,12 @@ BEGIN
|
||||
|
||||
INC(current_declaration, TSIZE(PAstConstantDeclaration))
|
||||
END;
|
||||
WriteLine(context^.output)
|
||||
IF extra_newline THEN
|
||||
WriteLine(context^.output)
|
||||
END
|
||||
END
|
||||
END transpile_constant_part;
|
||||
PROCEDURE transpile_module(context: PTranspilerContext; result: PAstModule);
|
||||
VAR
|
||||
token: LexerToken;
|
||||
BEGIN
|
||||
IF result^.main = FALSE THEN
|
||||
WriteString(context^.output, 'IMPLEMENTATION ')
|
||||
@ -127,9 +111,9 @@ BEGIN
|
||||
(* Write the module body. *)
|
||||
|
||||
transpile_import_part(context, result^.imports);
|
||||
transpile_constant_part(context, result^.constants);
|
||||
transpile_constant_part(context, result^.constants, TRUE);
|
||||
transpile_type_part(context, result^.types);
|
||||
transpile_variable_part(context, result^.variables);
|
||||
transpile_variable_part(context, result^.variables, TRUE);
|
||||
transpile_procedure_part(context, result^.procedures);
|
||||
transpile_statement_part(context, result^.statements);
|
||||
|
||||
@ -169,8 +153,6 @@ BEGIN
|
||||
WriteString(context^.output, ' END')
|
||||
END transpile_record_type;
|
||||
PROCEDURE transpile_pointer_type(context: PTranspilerContext; type_expression: PAstTypeExpression);
|
||||
VAR
|
||||
token: LexerToken;
|
||||
BEGIN
|
||||
WriteString(context^.output, 'POINTER TO ');
|
||||
|
||||
@ -306,7 +288,7 @@ BEGIN
|
||||
transpile_type_expression(context, declaration^.variable_type);
|
||||
write_semicolon(context^.output)
|
||||
END transpile_variable_declaration;
|
||||
PROCEDURE transpile_variable_part(context: PTranspilerContext; declarations: PPAstVariableDeclaration);
|
||||
PROCEDURE transpile_variable_part(context: PTranspilerContext; declarations: PPAstVariableDeclaration; extra_newline: BOOLEAN);
|
||||
VAR
|
||||
current_declaration: PPAstVariableDeclaration;
|
||||
BEGIN
|
||||
@ -320,12 +302,13 @@ BEGIN
|
||||
|
||||
INC(current_declaration, TSIZE(PAstVariableDeclaration))
|
||||
END;
|
||||
WriteLine(context^.output)
|
||||
IF extra_newline THEN
|
||||
WriteLine(context^.output)
|
||||
END
|
||||
END
|
||||
END transpile_variable_part;
|
||||
PROCEDURE transpile_procedure_heading(context: PTranspilerContext; declaration: PAstProcedureDeclaration);
|
||||
VAR
|
||||
token: LexerToken;
|
||||
written_bytes: CARDINAL;
|
||||
parameter_index: CARDINAL;
|
||||
current_parameter: PAstTypedDeclaration;
|
||||
@ -487,32 +470,32 @@ BEGIN
|
||||
END
|
||||
END transpile_expression;
|
||||
PROCEDURE transpile_if_statement(context: PTranspilerContext; statement: PAstStatement);
|
||||
VAR
|
||||
token: LexerToken;
|
||||
BEGIN
|
||||
IF statement <> NIL THEN
|
||||
WriteString(context^.output, ' IF ');
|
||||
transpile_expression(context, statement^.if_condition);
|
||||
WriteString(context^.output, 'IF ');
|
||||
transpile_expression(context, statement^.if_condition);
|
||||
|
||||
WriteString(context^.output, ' THEN');
|
||||
WriteLine(context^.output);
|
||||
WriteString(context^.output, ' THEN');
|
||||
WriteLine(context^.output);
|
||||
INC(context^.indentation);
|
||||
|
||||
transpile_compound_statement(context, statement^.if_branch);
|
||||
WriteString(context^.output, ' END')
|
||||
END
|
||||
transpile_compound_statement(context, statement^.if_branch);
|
||||
DEC(context^.indentation);
|
||||
indent(context);
|
||||
WriteString(context^.output, 'END')
|
||||
END transpile_if_statement;
|
||||
PROCEDURE transpile_while_statement(context: PTranspilerContext; statement: PAstStatement);
|
||||
VAR
|
||||
token: LexerToken;
|
||||
BEGIN
|
||||
WriteString(context^.output, ' WHILE ');
|
||||
WriteString(context^.output, 'WHILE ');
|
||||
transpile_expression(context, statement^.while_condition);
|
||||
|
||||
WriteString(context^.output, ' DO');
|
||||
WriteLine(context^.output);
|
||||
INC(context^.indentation);
|
||||
|
||||
transpile_compound_statement(context, statement^.while_body);
|
||||
WriteString(context^.output, ' END')
|
||||
DEC(context^.indentation);
|
||||
indent(context);
|
||||
WriteString(context^.output, 'END')
|
||||
END transpile_while_statement;
|
||||
PROCEDURE transpile_assignment_statement(context: PTranspilerContext; statement: PAstStatement);
|
||||
BEGIN
|
||||
@ -522,7 +505,7 @@ BEGIN
|
||||
END transpile_assignment_statement;
|
||||
PROCEDURE transpile_return_statement(context: PTranspilerContext; statement: PAstStatement);
|
||||
BEGIN
|
||||
WriteString(context^.output, ' RETURN ');
|
||||
WriteString(context^.output, 'RETURN ');
|
||||
|
||||
transpile_expression(context, statement^.returned)
|
||||
END transpile_return_statement;
|
||||
@ -548,6 +531,8 @@ BEGIN
|
||||
END transpile_compound_statement;
|
||||
PROCEDURE transpile_statement(context: PTranspilerContext; statement: PAstStatement);
|
||||
BEGIN
|
||||
indent(context);
|
||||
|
||||
IF statement^.kind = astStatementKindIf THEN
|
||||
transpile_if_statement(context, statement)
|
||||
END;
|
||||
@ -569,7 +554,10 @@ BEGIN
|
||||
IF compound.count > 0 THEN
|
||||
WriteString(context^.output, 'BEGIN');
|
||||
WriteLine(context^.output);
|
||||
transpile_compound_statement(context, compound)
|
||||
|
||||
INC(context^.indentation);
|
||||
transpile_compound_statement(context, compound);
|
||||
DEC(context^.indentation)
|
||||
END
|
||||
END transpile_statement_part;
|
||||
PROCEDURE transpile_procedure_declaration(context: PTranspilerContext; declaration: PAstProcedureDeclaration);
|
||||
@ -578,8 +566,8 @@ VAR
|
||||
BEGIN
|
||||
transpile_procedure_heading(context, declaration);
|
||||
|
||||
transpile_constant_part(context, declaration^.constants);
|
||||
transpile_variable_part(context, declaration^.variables);
|
||||
transpile_constant_part(context, declaration^.constants, FALSE);
|
||||
transpile_variable_part(context, declaration^.variables, FALSE);
|
||||
transpile_statement_part(context, declaration^.statements);
|
||||
|
||||
WriteString(context^.output, 'END ');
|
||||
@ -628,6 +616,7 @@ VAR
|
||||
BEGIN
|
||||
context.input_name := input_name;
|
||||
context.output := output;
|
||||
context.indentation := 0;
|
||||
|
||||
transpile_module(ADR(context), ast_module)
|
||||
END transpile;
|
||||
|
Reference in New Issue
Block a user