aboutsummaryrefslogtreecommitdiff
path: root/source/diagnostic.elna
diff options
context:
space:
mode:
Diffstat (limited to 'source/diagnostic.elna')
-rw-r--r--source/diagnostic.elna241
1 files changed, 241 insertions, 0 deletions
diff --git a/source/diagnostic.elna b/source/diagnostic.elna
new file mode 100644
index 0000000..771ce38
--- /dev/null
+++ b/source/diagnostic.elna
@@ -0,0 +1,241 @@
+(* 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
+import common, cstdio, cstdlib, lexer, ast
+
+type
+ ElnaErrorKind* = (
+ unexpected_token,
+ undefined_symbol,
+ undefined_member,
+ duplicate_declaration
+ )
+ ElnaError* = record(ElnaListNode)
+ kind: ElnaErrorKind;
+ position: ElnaPosition
+ end
+ ElnaErrorUnexpectedToken* = record(ElnaError)
+ expected: [16]ElnaLexerKind;
+ possibilities: Word;
+ got: ElnaLexerKind
+ end
+ ElnaErrorUndefinedSymbol* = record(ElnaError)
+ symbol_name: []const Word8
+ end
+ ElnaErrorUndefinedMember* = record(ElnaError)
+ aggregate_name: []const Word8;
+ member_name: []const Word8
+ end
+ ElnaErrorDuplicateDeclaration* = record(ElnaError)
+ symbol_name: []const Word8
+ end
+
+proc elna_error_unexpected_token_create*(cursor: ^ElnaLexerCursor; number_of_expected: Word) -> ^ElnaErrorUnexpectedToken
+var
+ parser_error: ^ElnaErrorUnexpectedToken
+begin
+ parser_error := malloc#[ElnaErrorUnexpectedToken](#size(ElnaErrorUnexpectedToken));
+ parser_error^.next := nil;
+ parser_error^.kind := ElnaErrorKind.unexpected_token;
+ parser_error^.position := cursor^.position;
+ parser_error^.possibilities := number_of_expected;
+ parser_error^.got := cursor^.token^.kind
+return parser_error
+
+proc elna_error_duplicate_declaration_create*(position: ElnaPosition; symbol_name: []const Word8) -> ^ElnaErrorDuplicateDeclaration
+var
+ declaration_error: ^ElnaErrorDuplicateDeclaration
+begin
+ declaration_error := malloc#[ElnaErrorDuplicateDeclaration](#size(ElnaErrorDuplicateDeclaration));
+ declaration_error^.next := nil;
+ declaration_error^.kind := ElnaErrorKind.duplicate_declaration;
+ declaration_error^.position := position;
+ declaration_error^.symbol_name := symbol_name
+return declaration_error
+
+proc elna_error_undefined_symbol_create*(position: ElnaPosition; symbol_name: []const Word8) -> ^ElnaErrorUndefinedSymbol
+var
+ result: ^ElnaErrorUndefinedSymbol
+begin
+ result := malloc#[ElnaErrorUndefinedSymbol](#size(ElnaErrorUndefinedSymbol));
+ result^.next := nil;
+ result^.kind := ElnaErrorKind.undefined_symbol;
+ result^.position := position;
+ result^.symbol_name := symbol_name
+return result
+
+proc elna_error_undefined_member_create*(position: ElnaPosition; aggregate, member: []const Word8) -> ^ElnaErrorUndefinedMember
+var
+ result: ^ElnaErrorUndefinedMember
+begin
+ result := malloc#[ElnaErrorUndefinedMember](#size(ElnaErrorUndefinedMember));
+ result^.next := nil;
+ result^.kind := ElnaErrorKind.undefined_member;
+ result^.position := position;
+ result^.aggregate_name := aggregate;
+ result^.member_name := member
+return result
+
+proc elna_error_print_token*(kind: ElnaLexerKind)
+begin
+ case kind of
+ ElnaLexerKind._const:
+ write_s("\"const\"")
+ | ElnaLexerKind._var:
+ write_s("\"var\"")
+ | ElnaLexerKind._proc:
+ write_s("\"proc\"")
+ | ElnaLexerKind._type:
+ write_s("\"type\"")
+ | ElnaLexerKind._begin:
+ write_s("\"begin\"")
+ | ElnaLexerKind._end:
+ write_s("\"end\"")
+ | ElnaLexerKind._if:
+ write_s("\"if\"")
+ | ElnaLexerKind._then:
+ write_s("\"then\"")
+ | ElnaLexerKind._else:
+ write_s("\"else\"")
+ | ElnaLexerKind._elsif:
+ write_s("\"elsif\"")
+ | ElnaLexerKind._extern:
+ write_s("\"extern\"")
+ | ElnaLexerKind._record:
+ write_s("\"record\"")
+ | ElnaLexerKind.boolean:
+ write_s("BOOLEAN")
+ | ElnaLexerKind.null:
+ write_s("NIL")
+ | ElnaLexerKind.and:
+ write_s("\"&\"")
+ | ElnaLexerKind._or:
+ write_s("\"or\"")
+ | ElnaLexerKind._xor:
+ write_s("\"xor\"")
+ | ElnaLexerKind.not:
+ write_s("\"~\"")
+ | ElnaLexerKind._return:
+ write_s("\"return\"")
+ | ElnaLexerKind._cast:
+ write_s("\"cast\"")
+ | ElnaLexerKind.trait:
+ write_s("TRAIT")
+ | ElnaLexerKind.left_paren:
+ write_s("\"(\"")
+ | ElnaLexerKind.right_paren:
+ write_s("\")\"")
+ | ElnaLexerKind.left_square:
+ write_s("\"[\"")
+ | ElnaLexerKind.right_square:
+ write_s("\"]\"")
+ | ElnaLexerKind.greater_equal:
+ write_s("\">=\"")
+ | ElnaLexerKind.less_equal:
+ write_s("\"<=\"")
+ | ElnaLexerKind.greater_than:
+ write_s("\">\"")
+ | ElnaLexerKind.less_than:
+ write_s("\"<\"")
+ | ElnaLexerKind.not_equal:
+ write_s("\"<>\"")
+ | ElnaLexerKind.equals:
+ write_s("\"=\"")
+ | ElnaLexerKind.semicolon:
+ write_s("\";\"")
+ | ElnaLexerKind.dot:
+ write_s("\".\"")
+ | ElnaLexerKind.comma:
+ write_s("\",\"")
+ | ElnaLexerKind.plus:
+ write_s("\"+\"")
+ | ElnaLexerKind.arrow:
+ write_s("\"->\"")
+ | ElnaLexerKind.minus:
+ write_s("\"-\"")
+ | ElnaLexerKind.multiplication:
+ write_s("\"*\"")
+ | ElnaLexerKind.division:
+ write_s("\"/\"")
+ | ElnaLexerKind.remainder:
+ write_s("\"%\"")
+ | ElnaLexerKind.assignment:
+ write_s("\":=\"")
+ | ElnaLexerKind.colon:
+ write_s("\":\"")
+ | ElnaLexerKind.hat:
+ write_s("\"^\"")
+ | ElnaLexerKind.at:
+ write_s("\"@\"")
+ | ElnaLexerKind.comment:
+ write_s("COMMENT")
+ | ElnaLexerKind.string:
+ write_s("STRING")
+ | ElnaLexerKind.character:
+ write_s("CHARACTER")
+ | ElnaLexerKind.integer:
+ write_s("INTEGER")
+ | ElnaLexerKind.word:
+ write_s("WORD")
+ | ElnaLexerKind.eof:
+ write_s("EOF")
+ else
+ write_s("UNKNOWN")
+ end
+return
+
+proc elna_error_print_unexpected_token*(current_error: ^ElnaErrorUnexpectedToken)
+begin
+ write_s("Parse error: Expecting token ");
+ elna_error_print_token(current_error^.expected[1]);
+ write_s("; got ");
+ elna_error_print_token(current_error^.got);
+ write_s(". ")
+return
+
+proc elna_error_print_undefined_member*(current_error: ^ElnaErrorUndefinedMember)
+begin
+ write_s("Semantic error: Member \"");
+ write_s(current_error^.member_name);
+ write_s("\" is not accessible on \"");
+ write_s(current_error^.aggregate_name);
+ write_s("\". ")
+return
+
+proc elna_error_print_undefined_symbol*(current_error: ^ElnaErrorUndefinedSymbol)
+begin
+ write_s("Semantic error: Undefined symbol \"");
+ write_s(current_error^.symbol_name);
+ write_s("\". ")
+return
+
+proc elna_error_print_duplicate_declaration*(current_error: ^ElnaErrorDuplicateDeclaration)
+begin
+ write_s("Semantic error: Duplicate declaration \"");
+ write_s(current_error^.symbol_name);
+ write_s("\". ")
+return
+
+proc elna_error_print*(current_error: ^ElnaError)
+begin
+ case current_error^.kind of
+ ElnaErrorKind.unexpected_token:
+ elna_error_print_unexpected_token(cast(current_error: ^ElnaErrorUnexpectedToken))
+ | ElnaErrorKind.undefined_symbol:
+ elna_error_print_undefined_symbol(cast(current_error: ^ElnaErrorUndefinedSymbol))
+ | ElnaErrorKind.undefined_member:
+ elna_error_print_undefined_member(cast(current_error: ^ElnaErrorUndefinedMember))
+ | ElnaErrorKind.duplicate_declaration:
+ elna_error_print_duplicate_declaration(cast(current_error: ^ElnaErrorDuplicateDeclaration))
+ else
+ write_s("Unknown error. ")
+ end;
+ write_s("Line ");
+ write_u(current_error^.position.start_location.line);
+ write_s(", column ");
+ write_u(current_error^.position.start_location.column);
+ write_s(".\n")
+return
+
+end.