Implement noreturn procedure declarations
This commit is contained in:
100
source.elna
100
source.elna
@ -60,6 +60,8 @@ const
|
||||
TOKEN_CHARACTER* = 55
|
||||
TOKEN_STRING* = 56
|
||||
TOKEN_DEFER* = 57
|
||||
TOKEN_EXCLAMATION* = 58
|
||||
TOKEN_ARROW = 59
|
||||
|
||||
type
|
||||
Position* = record
|
||||
@ -92,20 +94,6 @@ type
|
||||
tokenize: Bool
|
||||
syntax_tree: Bool
|
||||
end
|
||||
Literal* = record
|
||||
value: Int
|
||||
end
|
||||
ConstantDefinition* = record
|
||||
name: ^Char
|
||||
body: ^Literal
|
||||
end
|
||||
ConstantPart* = record
|
||||
elements: ^^ConstantDefinition
|
||||
count: Word
|
||||
end
|
||||
Program* = record
|
||||
constants: ConstantPart
|
||||
end
|
||||
|
||||
(*
|
||||
External procedures.
|
||||
@ -134,7 +122,7 @@ proc strlen(ptr: ^Char) -> Word; extern
|
||||
proc strtol(nptr: ^Char, endptr: ^^Char, base: Int) -> Int; extern
|
||||
|
||||
proc perror(s: ^Char); extern
|
||||
proc exit(code: Int); extern
|
||||
proc exit(code: Int) -> !; extern
|
||||
|
||||
(*
|
||||
Standard procedures.
|
||||
@ -567,6 +555,10 @@ begin
|
||||
write_s("\"...\"")
|
||||
elsif current_token^.kind = TOKEN_DEFER then
|
||||
write_s("DEFER")
|
||||
elsif current_token^.kind = TOKEN_EXCLAMATION then
|
||||
write_c('!')
|
||||
elsif current_token^.kind = TOKEN_ARROW then
|
||||
write_s("->")
|
||||
else
|
||||
write_s("UNKNOWN<")
|
||||
write_i(current_token^.kind)
|
||||
@ -772,8 +764,16 @@ begin
|
||||
current_token^.kind := TOKEN_PLUS
|
||||
source_code := advance_source(source_code, 1u)
|
||||
elsif first_char = '-' then
|
||||
current_token^.kind := TOKEN_MINUS
|
||||
source_code := advance_source(source_code, 1u)
|
||||
|
||||
if source_code.text.length = 0u then
|
||||
current_token^.kind := TOKEN_MINUS
|
||||
elsif source_code.text[1u] = '>' then
|
||||
current_token^.kind := TOKEN_ARROW
|
||||
source_code := advance_source(source_code, 1u)
|
||||
else
|
||||
current_token^.kind := TOKEN_MINUS
|
||||
end
|
||||
elsif first_char = '*' then
|
||||
current_token^.kind := TOKEN_MULTIPLICATION
|
||||
source_code := advance_source(source_code, 1u)
|
||||
@ -800,6 +800,9 @@ begin
|
||||
elsif first_char = '@' then
|
||||
current_token^.kind := TOKEN_AT
|
||||
source_code := advance_source(source_code, 1u)
|
||||
elsif first_char = '!' then
|
||||
current_token^.kind := TOKEN_EXCLAMATION
|
||||
source_code := advance_source(source_code, 1u)
|
||||
else
|
||||
current_token^.kind := 0
|
||||
source_code := advance_source(source_code, 1u)
|
||||
@ -818,68 +821,6 @@ begin
|
||||
return tokens
|
||||
end
|
||||
|
||||
proc parse_literal(tokens: ^^Token, tokens_size: ^Word) -> ^Literal;
|
||||
begin
|
||||
return cast(calloc(1u, Literal.size): ^Literal)
|
||||
end
|
||||
|
||||
proc parse_constant_definition(tokens: ^^Token,
|
||||
tokens_size: ^Word) -> ^ConstantDefinition;
|
||||
var
|
||||
result: ^ConstantDefinition
|
||||
begin
|
||||
result := cast(calloc(1u, ConstantDefinition.size): ^ConstantDefinition)
|
||||
|
||||
result^.name := cast(malloc(strlen(tokens^^.value.string_value)): ^Char)
|
||||
strcpy(result^.name, tokens^^.value.string_value)
|
||||
|
||||
tokens^ := tokens^ + 2u
|
||||
tokens_size := tokens_size - 2u
|
||||
|
||||
write_z(result^.name)
|
||||
write_c('\n')
|
||||
|
||||
result^.body := parse_literal(tokens, tokens_size)
|
||||
|
||||
tokens^ := tokens^ + 2u
|
||||
tokens_size := tokens_size - 2u
|
||||
|
||||
return result
|
||||
end
|
||||
|
||||
proc parse_program(tokens: ^^Token, tokens_size: ^Word) -> ^Program;
|
||||
var
|
||||
result: ^Program
|
||||
current_constant: ^^ConstantDefinition
|
||||
begin
|
||||
result := cast(calloc(1u, Program.size): ^Program)
|
||||
|
||||
result^.constants.elements := nil
|
||||
result^.constants.count := 0u
|
||||
|
||||
if tokens^^.kind = TOKEN_CONST then
|
||||
tokens^ := tokens^ + 1
|
||||
tokens_size^ := tokens_size^ - 1u
|
||||
|
||||
while tokens_size^ > 0u and tokens^^.kind = TOKEN_IDENTIFIER do
|
||||
result^.constants.elements := cast(
|
||||
reallocarray(
|
||||
cast(result^.constants.elements: ^Byte),
|
||||
result^.constants.count + 1u,
|
||||
(^ConstantDefinition).size
|
||||
) : ^^ConstantDefinition)
|
||||
current_constant := result^.constants.elements + result^.constants.count
|
||||
|
||||
result^.constants.count := result^.constants.count + 1u
|
||||
|
||||
current_constant^ := parse_constant_definition(tokens, tokens_size)
|
||||
if current_constant^ = nil then
|
||||
return nil
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
proc parse_command_line*(argc: Int, argv: ^^Char) -> ^CommandLine;
|
||||
var
|
||||
parameter: ^^Char
|
||||
@ -943,9 +884,6 @@ begin
|
||||
if command_line^.tokenize then
|
||||
print_tokens(tokens, tokens_size)
|
||||
end
|
||||
if command_line^.syntax_tree then
|
||||
parse_program(@tokens, @tokens_size)
|
||||
end
|
||||
return 0
|
||||
end
|
||||
|
||||
|
Reference in New Issue
Block a user