Allow comparing all pointer types to nil
This commit is contained in:
142
source.elna
142
source.elna
@ -1,3 +1,21 @@
|
||||
const
|
||||
SEEK_SET = 0, SEEK_CUR = 1, SEEK_END = 2,
|
||||
|
||||
TOKEN_IDENTIFIER = 1, TOKEN_IF = 2, TOKEN_THEN = 3, TOKEN_ELSE = 4, TOKEN_ELSIF = 5,
|
||||
TOKEN_WHILE = 6, TOKEN_DO = 7, TOKEN_PROC = 8, TOKEN_BEGIN = 9, TOKEN_END = 10,
|
||||
TOKEN_EXTERN = 11, TOKEN_CONST = 12, TOKEN_VAR = 13, TOKEN_ARRAY = 14, TOKEN_OF = 15,
|
||||
TOKEN_TYPE = 16, TOKEN_RECORD = 17, TOKEN_UNION = 18, TOKEN_POINTER = 19, TOKEN_TO = 20,
|
||||
TOKEN_BOOLEAN = 21, TOKEN_NIL = 22, TOKEN_AND = 23, TOKEN_OR = 24, TOKEN_NOT = 25,
|
||||
TOKEN_RETURN = 26, TOKEN_CAST = 27, TOKEN_AS = 28, TOKEN_SIZEOF = 29,
|
||||
TOKEN_LEFT_PAREN = 30, TOKEN_RIGHT_PAREN = 31, TOKEN_LEFT_SQUARE = 32,
|
||||
TOKEN_RIGHT_SQUARE = 33, TOKEN_GREATER_EQUAL = 34, TOKEN_LESS_EQUAL = 35,
|
||||
TOKEN_GREATER_THAN = 36, TOKEN_LESS_THAN = 37, TOKEN_NOT_EQUAL = 38, TOKEN_EQUAL = 39,
|
||||
TOKEN_SEMICOLON = 40, TOKEN_DOT = 41, TOKEN_COMMA = 42,
|
||||
TOKEN_PLUS = 43, TOKEN_MINUS = 44, TOKEN_MULTIPLICATION = 45, TOKEN_DIVISION = 46,
|
||||
TOKEN_REMAINDER = 47, TOKEN_ASSIGNMENT = 48, TOKEN_COLON = 49, TOKEN_HAT = 50,
|
||||
TOKEN_AT = 51, TOKEN_COMMENT = 52, TOKEN_INTEGER = 53, TOKEN_WORD = 54,
|
||||
TOKEN_CHARACTER = 55, TOKEN_STRING = 56;
|
||||
|
||||
type
|
||||
Position = record
|
||||
line: Word;
|
||||
@ -23,32 +41,29 @@ type
|
||||
end,
|
||||
CommandLine = record
|
||||
input: pointer to Char
|
||||
end,
|
||||
Literal = record
|
||||
value: Int
|
||||
end,
|
||||
ConstantDefinition = record
|
||||
name: pointer to Char;
|
||||
body: pointer to Literal
|
||||
end,
|
||||
ConstantPart = record
|
||||
elements: pointer to pointer to ConstantDefinition;
|
||||
count: Word
|
||||
end,
|
||||
Program = record
|
||||
constants: ConstantPart
|
||||
end;
|
||||
|
||||
const
|
||||
SEEK_SET = 0, SEEK_CUR = 1, SEEK_END = 2,
|
||||
|
||||
TOKEN_IDENTIFIER = 1, TOKEN_IF = 2, TOKEN_THEN = 3, TOKEN_ELSE = 4, TOKEN_ELSIF = 5,
|
||||
TOKEN_WHILE = 6, TOKEN_DO = 7, TOKEN_PROC = 8, TOKEN_BEGIN = 9, TOKEN_END = 10,
|
||||
TOKEN_EXTERN = 11, TOKEN_CONST = 12, TOKEN_VAR = 13, TOKEN_ARRAY = 14, TOKEN_OF = 15,
|
||||
TOKEN_TYPE = 16, TOKEN_RECORD = 17, TOKEN_UNION = 18, TOKEN_POINTER = 19, TOKEN_TO = 20,
|
||||
TOKEN_BOOLEAN = 21, TOKEN_NIL = 22, TOKEN_AND = 23, TOKEN_OR = 24, TOKEN_NOT = 25,
|
||||
TOKEN_RETURN = 26, TOKEN_CAST = 27, TOKEN_AS = 28, TOKEN_SIZEOF = 29,
|
||||
TOKEN_LEFT_PAREN = 30, TOKEN_RIGHT_PAREN = 31, TOKEN_LEFT_SQUARE = 32,
|
||||
TOKEN_RIGHT_SQUARE = 33, TOKEN_GREATER_EQUAL = 34, TOKEN_LESS_EQUAL = 35,
|
||||
TOKEN_GREATER_THAN = 36, TOKEN_LESS_THAN = 37, TOKEN_NOT_EQUAL = 38, TOKEN_EQUAL = 39,
|
||||
TOKEN_SEMICOLON = 40, TOKEN_DOT = 41, TOKEN_COMMA = 42,
|
||||
TOKEN_PLUS = 43, TOKEN_MINUS = 44, TOKEN_MULTIPLICATION = 45, TOKEN_DIVISION = 46,
|
||||
TOKEN_REMAINDER = 47, TOKEN_ASSIGNMENT = 48, TOKEN_COLON = 49, TOKEN_HAT = 50,
|
||||
TOKEN_AT = 51, TOKEN_COMMENT = 52, TOKEN_INTEGER = 53, TOKEN_WORD = 54,
|
||||
TOKEN_CHARACTER = 55, TOKEN_STRING = 56;
|
||||
|
||||
(*
|
||||
External procedures.
|
||||
*)
|
||||
proc fopen(pathname: String, mode: String): pointer to FILE; extern;
|
||||
proc fclose(stream: pointer to FILE): Int; extern;
|
||||
proc fseek(stream: pointer to FILE, off: Int, whence: Int): Int; extern;
|
||||
proc rewind(stream: pointer to FILE); extern;
|
||||
proc ftell(stream: pointer to FILE): Int; extern;
|
||||
proc fread(ptr: pointer to Byte, size: Word, nmemb: Word, stream: pointer to FILE): Word; extern;
|
||||
proc write(fd: Int, buf: pointer to Byte, Word: Int): Int; extern;
|
||||
@ -63,10 +78,12 @@ proc memset(ptr: pointer to Char, c: Int, n: Int): pointer to Char; extern;
|
||||
|
||||
proc strncmp(s1: pointer to Char, s2: pointer to Char, n: Word): Int; extern;
|
||||
proc strncpy(dst: pointer to Char, src: pointer to Char, dsize: Word): pointer to Char; extern;
|
||||
proc strcpy(dst: pointer to Char, src: pointer to Char): pointer to Char; extern;
|
||||
proc strlen(ptr: pointer to Char): Word; extern;
|
||||
|
||||
proc strtol(nptr: pointer to Char, endptr: pointer to pointer to Char, base: Int): Int; extern;
|
||||
|
||||
proc perror(s: pointer to Char); extern;
|
||||
proc exit(code: Int); extern;
|
||||
|
||||
(*
|
||||
@ -152,13 +169,24 @@ var
|
||||
begin
|
||||
input_file := fopen(filename, "rb");
|
||||
|
||||
fseek(input_file, 0, SEEK_END);
|
||||
if input_file = nil then
|
||||
return nil
|
||||
end;
|
||||
if fseek(input_file, 0, SEEK_END) <> 0 then
|
||||
fclose(input_file);
|
||||
return nil
|
||||
end;
|
||||
source_size := ftell(input_file);
|
||||
fseek(input_file, 0, SEEK_SET);
|
||||
if source_size < 0 then
|
||||
fclose(input_file);
|
||||
return nil
|
||||
end;
|
||||
rewind(input_file);
|
||||
|
||||
input := calloc(source_size + 1, 1);
|
||||
fread(input, source_size, 1, input_file);
|
||||
|
||||
if fread(input, source_size, 1, input_file) <> 1u then
|
||||
input := cast(nil as pointer to Byte)
|
||||
end;
|
||||
fclose(input_file);
|
||||
|
||||
return input
|
||||
@ -551,7 +579,7 @@ begin
|
||||
if input_pointer^ = '*' then
|
||||
token_end := lex_comment(input_pointer + 1);
|
||||
|
||||
if token_end <> cast(nil as pointer to Char) then
|
||||
if token_end <> nil then
|
||||
token_length := cast(token_end as Word) - cast(input_pointer as Word);
|
||||
current_token^.value.string_value := cast(calloc(token_length + 1u, 1) as pointer to Char);
|
||||
strncpy(current_token^.value.string_value, input_pointer, token_length);
|
||||
@ -667,6 +695,65 @@ begin
|
||||
return tokens
|
||||
end;
|
||||
|
||||
proc parse_literal(tokens: pointer to pointer to Token, tokens_size: pointer to Word): pointer to Literal;
|
||||
begin
|
||||
return cast(calloc(1, sizeof(Literal)) as pointer to Literal)
|
||||
end;
|
||||
|
||||
proc parse_constant_definition(tokens: pointer to pointer to Token,
|
||||
tokens_size: pointer to Word): pointer to ConstantDefinition;
|
||||
var
|
||||
result: pointer to ConstantDefinition;
|
||||
begin
|
||||
result := cast(calloc(1, sizeof(ConstantDefinition)) as pointer to ConstantDefinition);
|
||||
|
||||
result^.name := cast(malloc(strlen(tokens^^.value.string_value)) as pointer to Char);
|
||||
strcpy(result^.name, tokens^^.value.string_value);
|
||||
|
||||
tokens^ := tokens^ + sizeof(Token) * 2u;
|
||||
tokens_size := tokens_size - sizeof(Token) * 2u;
|
||||
|
||||
write_s(result^.name);
|
||||
write_c('\n');
|
||||
|
||||
result^.body := parse_literal(tokens, tokens_size);
|
||||
|
||||
tokens^ := tokens^ + sizeof(Token) * 2u;
|
||||
tokens_size := tokens_size - sizeof(Token) * 2u;
|
||||
|
||||
return result
|
||||
end;
|
||||
|
||||
proc parse_program(tokens: pointer to pointer to Token, tokens_size: pointer to Word): pointer to Program;
|
||||
var
|
||||
result: pointer to Program,
|
||||
current_constant: pointer to pointer to ConstantDefinition;
|
||||
begin
|
||||
result := cast(calloc(1, sizeof(Program)) as pointer to Program);
|
||||
|
||||
result^.constants.elements := cast(nil as pointer to pointer to ConstantDefinition);
|
||||
result^.constants.count := 0u;
|
||||
|
||||
if tokens^^.kind = TOKEN_CONST then
|
||||
tokens^ := tokens^ + sizeof(Token);
|
||||
tokens_size^ := tokens_size^ - sizeof(Token);
|
||||
|
||||
while tokens_size^ > 0u and tokens^^.kind = TOKEN_IDENTIFIER do
|
||||
result^.constants.elements := cast(
|
||||
reallocarray(result^.constants.elements, result^.constants.count + 1u, sizeof(pointer to ConstantDefinition))
|
||||
as pointer to pointer to ConstantDefinition);
|
||||
current_constant := result^.constants.elements + result^.constants.count * sizeof(pointer to ConstantDefinition);
|
||||
|
||||
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: pointer to pointer to Char): pointer to CommandLine;
|
||||
var
|
||||
parameter: pointer to pointer to Char,
|
||||
@ -712,11 +799,16 @@ begin
|
||||
return 2
|
||||
end;
|
||||
input := read_source(command_line^.input);
|
||||
if input = nil then
|
||||
perror(command_line^.input);
|
||||
return 3
|
||||
end;
|
||||
tokens := tokenize(input, @tokens_size);
|
||||
|
||||
free(input);
|
||||
print_tokens(tokens, tokens_size);
|
||||
|
||||
print_tokens(tokens, tokens_size)
|
||||
parse_program(@tokens, @tokens_size);
|
||||
return 0
|
||||
end;
|
||||
|
||||
begin
|
||||
|
Reference in New Issue
Block a user