Add semicolons back
This commit is contained in:
		| @@ -126,7 +126,9 @@ along with GCC; see the file COPYING3.  If not see | ||||
| %type <elna::boot::variable_declaration *> formal_parameter | ||||
| %type <std::shared_ptr<elna::boot::top_type>> type_expression; | ||||
| %type <elna::boot::traits_expression *> traits_expression; | ||||
| %type <elna::boot::expression *> expression operand unary; | ||||
| %type <elna::boot::expression *> expression operand; | ||||
| %type <elna::boot::unary_expression *> unary_expression; | ||||
| %type <elna::boot::binary_expression *> binary_expression; | ||||
| %type <std::vector<elna::boot::expression *>> expressions actual_parameter_list; | ||||
| %type <elna::boot::designator_expression *> designator_expression; | ||||
| %type <elna::boot::assign_statement *> assign_statement; | ||||
| @@ -143,7 +145,7 @@ along with GCC; see the file COPYING3.  If not see | ||||
| %type <std::vector<elna::boot::type_definition *>> type_definitions type_part; | ||||
| %type <elna::boot::block *> block; | ||||
| %type <elna::boot::field_t> field_declaration; | ||||
| %type <std::vector<std::pair<std::string, std::shared_ptr<elna::boot::top_type>>>> optional_fields fields; | ||||
| %type <std::vector<std::pair<std::string, std::shared_ptr<elna::boot::top_type>>>> optional_fields required_fields; | ||||
| %type <std::vector<elna::boot::conditional_statements *>> elsif_then_statements elsif_do_statements; | ||||
| %type <elna::boot::cast_expression *> cast_expression; | ||||
| %type <std::pair<std::string, bool>> identifier_definition; | ||||
| @@ -321,8 +323,11 @@ operand: | ||||
|     | call_expression { $$ = $1; } | ||||
|     | "(" expression ")" { $$ = $2; } | ||||
| expression: | ||||
|     unary { $$ = $1; } | ||||
|     | expression "*" expression | ||||
|     unary_expression { $$ = $1; } | ||||
|     | binary_expression { $$ = $1; } | ||||
|     | operand { $$ = $1; } | ||||
| binary_expression: | ||||
|     expression "*" expression | ||||
|         { | ||||
|             $$ = new elna::boot::binary_expression(elna::boot::make_position(@2), $1, $3, | ||||
|                 elna::boot::binary_operator::multiplication); | ||||
| @@ -402,7 +407,7 @@ expression: | ||||
|             $$ = new elna::boot::binary_expression(elna::boot::make_position(@2), $1, $3, | ||||
|                 elna::boot::binary_operator::shift_right); | ||||
|         } | ||||
| unary: | ||||
| unary_expression: | ||||
|     "@" operand | ||||
|         { | ||||
|             $$ = new elna::boot::unary_expression(elna::boot::make_position(@1), $2, | ||||
| @@ -418,7 +423,6 @@ unary: | ||||
|             $$ = new elna::boot::unary_expression(elna::boot::make_position(@1), $2, | ||||
|                 elna::boot::unary_operator::minus); | ||||
|         } | ||||
|     | operand { $$ = $1; } | ||||
| expressions: | ||||
|     expression "," expressions | ||||
|         { | ||||
| @@ -449,26 +453,30 @@ statement: | ||||
|     | if_statement { $$ = $1; } | ||||
|     | call_expression { $$ = $1; } | ||||
| statements: | ||||
|     statement statements | ||||
|     statement ";" statements | ||||
|         { | ||||
|             std::swap($$, $2); | ||||
|             std::swap($$, $3); | ||||
|             $$.emplace($$.cbegin(), $1); | ||||
|         } | ||||
|     | statement | ||||
|         { | ||||
|             $$.push_back($1); | ||||
|         } | ||||
|     | /* no statements */ {} | ||||
| statement_part: | ||||
|     "begin" statements { std::swap($$, $2); } | ||||
|     | {} | ||||
| field_declaration: | ||||
|     IDENTIFIER ":" type_expression { $$ = std::make_pair($1, $3); } | ||||
| fields: | ||||
|     field_declaration fields | ||||
| required_fields: | ||||
|     field_declaration required_fields | ||||
|         { | ||||
|             std::swap($$, $2); | ||||
|             $$.emplace($$.cbegin(), $1); | ||||
|         } | ||||
|     | field_declaration { $$.emplace_back($1); } | ||||
| optional_fields: | ||||
|     fields { std::swap($$, $1); } | ||||
|     required_fields { std::swap($$, $1); } | ||||
|     | /* no fields */ {} | ||||
| type_expression: | ||||
|     "[" INTEGER "]" type_expression | ||||
| @@ -483,7 +491,7 @@ type_expression: | ||||
|         { | ||||
|             $$ = std::make_shared<elna::boot::record_type>(elna::boot::make_position(@1), std::move($2)); | ||||
|         } | ||||
|     | "union" fields "end" | ||||
|     | "union" required_fields "end" | ||||
|         { | ||||
|             $$ = std::make_shared<elna::boot::union_type>(elna::boot::make_position(@1), std::move($2)); | ||||
|         } | ||||
| @@ -523,12 +531,11 @@ constant_definitions: | ||||
|     constant_definition constant_definitions | ||||
|         { | ||||
|             std::swap($$, $2); | ||||
|             $$.emplace($$.cbegin(), std::move($1)); | ||||
|             $$.insert($$.cbegin(), $1); | ||||
|         } | ||||
|     | constant_definition { $$.emplace_back(std::move($1)); } | ||||
|     | /* no constant definitions */ {} | ||||
| constant_part: | ||||
|     /* no constant definitions */ {} | ||||
|     | "const" {} | ||||
|     {} | ||||
|     | "const" constant_definitions { std::swap($$, $2); } | ||||
| type_definition: identifier_definition "=" type_expression | ||||
|         { | ||||
| @@ -538,9 +545,9 @@ type_definitions: | ||||
|     type_definition type_definitions | ||||
|         { | ||||
|             std::swap($$, $2); | ||||
|             $$.emplace($$.cbegin(), std::move($1)); | ||||
|             $$.insert($$.cbegin(), $1); | ||||
|         } | ||||
|     | type_definition { $$.emplace_back(std::move($1)); } | ||||
|     | type_definition { $$.push_back($1); } | ||||
| type_part: | ||||
|     /* no type definitions */ {} | ||||
|     | "type" {} | ||||
|   | ||||
							
								
								
									
										300
									
								
								source.elna
									
									
									
									
									
								
							
							
						
						
									
										300
									
								
								source.elna
									
									
									
									
									
								
							| @@ -173,20 +173,20 @@ var | ||||
|   n: Word | ||||
|   buffer: [10]Char | ||||
| begin | ||||
|   n := 10u | ||||
|   n := 10u; | ||||
|  | ||||
|   if value = 0 then | ||||
|     write_c('0') | ||||
|   end | ||||
|   end; | ||||
|   while value <> 0 do | ||||
|     digit := value % 10 | ||||
| 	value := value / 10 | ||||
|     digit := value % 10; | ||||
| 	value := value / 10; | ||||
|  | ||||
| 	buffer[n] := cast(cast('0': Int) + digit: Char) | ||||
| 	buffer[n] := cast(cast('0': Int) + digit: Char); | ||||
| 	n := n - 1u | ||||
|   end | ||||
|   end; | ||||
|   while n < 10u do | ||||
|     n := n + 1u | ||||
|     n := n + 1u; | ||||
|     write_c(buffer[n]) | ||||
|   end | ||||
| end | ||||
| @@ -224,8 +224,8 @@ proc string_dup(origin: String) -> String; | ||||
| var | ||||
|   copy: ^Char | ||||
| begin | ||||
|   copy := cast(malloc(origin.length): ^Char) | ||||
|   strncpy(copy, origin.ptr, origin.length) | ||||
|   copy := cast(malloc(origin.length): ^Char); | ||||
|   strncpy(copy, origin.ptr, origin.length); | ||||
|  | ||||
|   return String(copy, origin.length) | ||||
| end | ||||
| @@ -234,9 +234,9 @@ proc string_buffer_new() -> StringBuffer; | ||||
| var | ||||
|   result: StringBuffer | ||||
| begin | ||||
|   result.capacity := 64u | ||||
|   result.data := malloc(result.capacity) | ||||
|   result.size := 0u | ||||
|   result.capacity := 64u; | ||||
|   result.data := malloc(result.capacity); | ||||
|   result.size := 0u; | ||||
|  | ||||
|   return result | ||||
| end | ||||
| @@ -244,10 +244,10 @@ end | ||||
| proc string_buffer_push(buffer: ^StringBuffer, char: Char); | ||||
| begin | ||||
|   if buffer^.size >= buffer^.capacity then | ||||
|     buffer^.capacity := buffer^.capacity + 1024u | ||||
|     buffer^.capacity := buffer^.capacity + 1024u; | ||||
|     buffer^.data := realloc(buffer^.data, buffer^.capacity) | ||||
|   end | ||||
|   (buffer^.data + buffer^.size)^ := cast(char: Byte) | ||||
|   end; | ||||
|   (buffer^.data + buffer^.size)^ := cast(char: Byte); | ||||
|   buffer^.size := buffer^.size + 1u | ||||
| end | ||||
|  | ||||
| @@ -260,8 +260,8 @@ proc string_buffer_clear(buffer: ^StringBuffer) -> String; | ||||
| var | ||||
|   result: String | ||||
| begin | ||||
|   result := String(cast(buffer^.data: ^Char), buffer^.size) | ||||
|   buffer^.size := 0u | ||||
|   result := String(cast(buffer^.data: ^Char), buffer^.size); | ||||
|   buffer^.size := 0u; | ||||
|   return result | ||||
| end | ||||
|  | ||||
| @@ -278,12 +278,12 @@ var | ||||
|   result: ^SourceFile | ||||
|   file_handle: ^FILE | ||||
| begin | ||||
|   file_handle := fopen(filename, "rb\0".ptr) | ||||
|   file_handle := fopen(filename, "rb\0".ptr); | ||||
|  | ||||
|   if file_handle <> nil then | ||||
|     result := cast(malloc(#size(SourceFile)): ^SourceFile) | ||||
|     result^.handle := file_handle | ||||
|     result^.size := 0u | ||||
|     result := cast(malloc(#size(SourceFile)): ^SourceFile); | ||||
|     result^.handle := file_handle; | ||||
|     result^.size := 0u; | ||||
|     result^.index := 1u | ||||
|   end | ||||
|   return result | ||||
| @@ -294,44 +294,44 @@ var | ||||
|   successful: Bool | ||||
| begin | ||||
|   if escape = 'n' then | ||||
| 	result^ := '\n' | ||||
| 	successful := true | ||||
| 	result^ := '\n'; | ||||
| 	successful := true; | ||||
|   elsif escape = 'a' then | ||||
| 	result^ := '\a' | ||||
| 	result^ := '\a'; | ||||
| 	successful := true | ||||
|   elsif escape = 'b' then | ||||
| 	result^ := '\b' | ||||
| 	result^ := '\b'; | ||||
| 	successful := true | ||||
|   elsif escape = 't' then | ||||
| 	result^ := '\t' | ||||
| 	result^ := '\t'; | ||||
| 	successful := true | ||||
|   elsif escape = 'f' then | ||||
| 	result^ := '\f' | ||||
| 	result^ := '\f'; | ||||
| 	successful := true | ||||
|   elsif escape = 'r' then | ||||
| 	result^ := '\r' | ||||
| 	result^ := '\r'; | ||||
| 	successful := true | ||||
|   elsif escape = 'v' then | ||||
| 	result^ := '\v' | ||||
| 	result^ := '\v'; | ||||
| 	successful := true | ||||
|   elsif escape = '\\' then | ||||
| 	result^ := '\\' | ||||
| 	result^ := '\\'; | ||||
| 	successful := true | ||||
|   elsif escape = '\'' then | ||||
| 	result^ := '\'' | ||||
| 	result^ := '\''; | ||||
| 	successful := true | ||||
|   elsif escape = '"' then | ||||
| 	result^ := '"' | ||||
| 	result^ := '"'; | ||||
| 	successful := true | ||||
|   elsif escape = '?' then | ||||
| 	result^ := '\?' | ||||
| 	result^ := '\?'; | ||||
| 	successful := true | ||||
|   elsif escape = '0' then | ||||
| 	result^ := '\0' | ||||
| 	result^ := '\0'; | ||||
| 	successful := true | ||||
|   else | ||||
|     successful := false | ||||
|   end | ||||
|   end; | ||||
|   return successful | ||||
| end | ||||
|  | ||||
| @@ -339,10 +339,10 @@ proc source_file_empty(source_input: ^Byte) -> Bool; | ||||
| var | ||||
|   source_file: ^SourceFile | ||||
| begin | ||||
|   source_file := cast(source_input: ^SourceFile) | ||||
|   source_file := cast(source_input: ^SourceFile); | ||||
|  | ||||
|   if source_file^.index > source_file^.size then | ||||
|     source_file^.size := fread(cast(@source_file^.buffer: ^Byte), 1u, 1024u, source_file^.handle) | ||||
|     source_file^.size := fread(cast(@source_file^.buffer: ^Byte), 1u, 1024u, source_file^.handle); | ||||
| 	source_file^.index := 1u | ||||
|   end | ||||
|  | ||||
| @@ -353,7 +353,7 @@ proc source_file_head(source_input: ^Byte) -> Char; | ||||
| var | ||||
|   source_file: ^SourceFile | ||||
| begin | ||||
|   source_file := cast(source_input: ^SourceFile) | ||||
|   source_file := cast(source_input: ^SourceFile); | ||||
|  | ||||
|   return source_file^.buffer[source_file^.index] | ||||
| end | ||||
| @@ -362,7 +362,7 @@ proc source_file_advance(source_input: ^Byte); | ||||
| var | ||||
|   source_file: ^SourceFile | ||||
| begin | ||||
|   source_file := cast(source_input: ^SourceFile) | ||||
|   source_file := cast(source_input: ^SourceFile); | ||||
|  | ||||
|   source_file^.index := source_file^.index + 1u | ||||
| end | ||||
| @@ -377,13 +377,13 @@ end | ||||
|  | ||||
| proc source_code_advance(source_code: ^SourceCode); | ||||
| begin | ||||
|   source_code^.advance(source_code^.input) | ||||
|   source_code^.advance(source_code^.input); | ||||
|   source_code^.position.column := source_code^.position.column | ||||
| end | ||||
|  | ||||
| proc source_code_break(source_code: ^SourceCode); | ||||
| begin | ||||
|   source_code^.position.line := source_code^.position.line + 1u | ||||
|   source_code^.position.line := source_code^.position.line + 1u; | ||||
|   source_code^.position.column := 0u | ||||
| end | ||||
|  | ||||
| @@ -396,7 +396,7 @@ begin | ||||
|   while not source_code_empty(source_code) and is_space(source_code_head(source_code^)) do | ||||
|     if source_code_head(source_code^) = '\n' then | ||||
|       source_code_break(source_code) | ||||
| 	end | ||||
| 	end; | ||||
| 	source_code_advance(source_code) | ||||
|   end | ||||
| end | ||||
| @@ -410,7 +410,7 @@ var | ||||
|   content_length: Word | ||||
| begin | ||||
|   while not source_code_empty(source_code) and is_ident(source_code_head(source_code^)) do | ||||
|     string_buffer_push(token_content, source_code_head(source_code^)) | ||||
|     string_buffer_push(token_content, source_code_head(source_code^)); | ||||
| 	source_code_advance(source_code) | ||||
|   end | ||||
| end | ||||
| @@ -419,19 +419,19 @@ proc lex_comment(source_code: ^SourceCode, token_content: ^StringBuffer) -> Bool | ||||
| var | ||||
|   trailing: Word | ||||
| begin | ||||
|   trailing := 0u | ||||
|   trailing := 0u; | ||||
|  | ||||
|   while not source_code_empty(source_code) and trailing < 2u do | ||||
|     if source_code_head(source_code^) = '*' then | ||||
| 	  string_buffer_push(token_content, '*') | ||||
| 	  string_buffer_push(token_content, '*'); | ||||
| 	  trailing := 1u | ||||
| 	elsif source_code_head(source_code^) = ')' and trailing = 1u then | ||||
|       string_buffer_pop(token_content, 1u) | ||||
|       string_buffer_pop(token_content, 1u); | ||||
| 	  trailing := 2u | ||||
| 	else | ||||
| 	  string_buffer_push(token_content, source_code_head(source_code^)) | ||||
| 	  string_buffer_push(token_content, source_code_head(source_code^)); | ||||
| 	  trailing := 0u | ||||
| 	end | ||||
| 	end; | ||||
|     source_code_advance(source_code) | ||||
|   end | ||||
|  | ||||
| @@ -442,18 +442,18 @@ proc lex_character(source_code: ^SourceCode, token_content: ^Char) -> Bool; | ||||
| var | ||||
|   successful: Bool | ||||
| begin | ||||
|   successful := not source_code_empty(source_code) | ||||
|   successful := not source_code_empty(source_code); | ||||
|  | ||||
|   if successful then | ||||
|     if source_code_head(source_code^) = '\\' then | ||||
|       source_code_advance(source_code) | ||||
|       source_code_advance(source_code); | ||||
|  | ||||
|       successful := not source_code_empty(source_code) and escape_char(source_code_head(source_code^), token_content) | ||||
| 	else | ||||
|       token_content^ := source_code_head(source_code^) | ||||
|       token_content^ := source_code_head(source_code^); | ||||
| 	  successful := true | ||||
|     end | ||||
|   end | ||||
|   end; | ||||
|   if successful then | ||||
|     source_code_advance(source_code) | ||||
|   end | ||||
| @@ -467,15 +467,15 @@ var | ||||
|   is_valid: Bool | ||||
|   next_char: Char | ||||
| begin | ||||
|   is_valid := true | ||||
|   is_valid := true; | ||||
|  | ||||
|   while is_valid and not source_code_empty(source_code) and source_code_head(source_code^) <> '"' do | ||||
|     is_valid := lex_character(source_code, @next_char) | ||||
|     is_valid := lex_character(source_code, @next_char); | ||||
|  | ||||
|     if is_valid then | ||||
|       string_buffer_push(token_content, next_char) | ||||
|     end | ||||
|   end | ||||
|   end; | ||||
|  | ||||
|   if is_valid and source_code_expect(source_code, '"') then | ||||
|     source_code_advance(source_code) | ||||
| @@ -487,10 +487,10 @@ end | ||||
|  | ||||
| proc lex_number(source_code: ^SourceCode, token_content: ^Int); | ||||
| begin | ||||
|   token_content^ := 0 | ||||
|   token_content^ := 0; | ||||
|  | ||||
|   while not source_code_empty(source_code) and is_digit(source_code_head(source_code^)) 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) | ||||
|   end | ||||
| @@ -501,9 +501,9 @@ var | ||||
|   current_token: ^Token | ||||
|   i: Word | ||||
| begin | ||||
|   i := 0u | ||||
|   i := 0u; | ||||
|   while i < tokens_size do | ||||
|     current_token := tokens + i | ||||
|     current_token := tokens + i; | ||||
|  | ||||
|     if current_token^.kind = TOKEN_IF then | ||||
| 	  write_s("IF") | ||||
| @@ -544,8 +544,8 @@ begin | ||||
| 	elsif current_token^.kind = TOKEN_TO then | ||||
| 	  write_s("TO") | ||||
| 	elsif current_token^.kind = TOKEN_BOOLEAN then | ||||
| 	  write_s("BOOLEAN<") | ||||
| 	  write_b(current_token^.value.boolean_value) | ||||
| 	  write_s("BOOLEAN<"); | ||||
| 	  write_b(current_token^.value.boolean_value); | ||||
| 	  write_c('>') | ||||
| 	elsif current_token^.kind = TOKEN_NIL then | ||||
| 	  write_s("NIL") | ||||
| @@ -564,8 +564,8 @@ begin | ||||
| 	elsif current_token^.kind = TOKEN_SHIFT_RIGHT then | ||||
| 	  write_s(">>") | ||||
| 	elsif current_token^.kind = TOKEN_IDENTIFIER then | ||||
| 	  write_c('<') | ||||
|       write_s(current_token^.value.string) | ||||
| 	  write_c('<'); | ||||
|       write_s(current_token^.value.string); | ||||
| 	  write_c('>') | ||||
| 	elsif current_token^.kind = TOKEN_LEFT_PAREN then | ||||
| 	  write_s("(") | ||||
| @@ -614,16 +614,16 @@ begin | ||||
| 	elsif current_token^.kind = TOKEN_COMMENT then | ||||
| 	  write_s("(* COMMENT *)") | ||||
| 	elsif current_token^.kind = TOKEN_INTEGER then | ||||
| 	  write_c('<') | ||||
|       write_i(current_token^.value.int_value) | ||||
| 	  write_c('<'); | ||||
|       write_i(current_token^.value.int_value); | ||||
| 	  write_c('>') | ||||
| 	elsif current_token^.kind = TOKEN_WORD then | ||||
| 	  write_c('<') | ||||
|       write_i(current_token^.value.int_value) | ||||
| 	  write_c('<'); | ||||
|       write_i(current_token^.value.int_value); | ||||
| 	  write_s("u>") | ||||
| 	elsif current_token^.kind = TOKEN_CHARACTER then | ||||
| 	  write_c('<') | ||||
|       write_i(cast(current_token^.value.char_value: Int)) | ||||
| 	  write_c('<'); | ||||
|       write_i(cast(current_token^.value.char_value: Int)); | ||||
| 	  write_s("c>") | ||||
| 	elsif current_token^.kind = TOKEN_STRING then | ||||
| 	  write_s("\"...\"") | ||||
| @@ -634,14 +634,14 @@ begin | ||||
| 	elsif current_token^.kind = TOKEN_ARROW then | ||||
| 	  write_s("->") | ||||
| 	else | ||||
| 	  write_s("UNKNOWN<") | ||||
| 	  write_i(current_token^.kind) | ||||
| 	  write_s("UNKNOWN<"); | ||||
| 	  write_i(current_token^.kind); | ||||
| 	  write_c('>') | ||||
| 	end | ||||
| 	write_c(' ') | ||||
| 	end; | ||||
| 	write_c(' '); | ||||
|  | ||||
| 	i := i + 1u | ||||
|   end | ||||
| 	i := i + 1u; | ||||
|   end; | ||||
|   write_c('\n') | ||||
| end | ||||
|  | ||||
| @@ -688,10 +688,10 @@ begin | ||||
|   elsif "to" = token_content then | ||||
| 	current_token.kind := TOKEN_TO | ||||
|   elsif "true" = token_content then | ||||
| 	current_token.kind := TOKEN_BOOLEAN | ||||
| 	current_token.kind := TOKEN_BOOLEAN; | ||||
| 	current_token.value.boolean_value := true | ||||
|   elsif "false" = token_content then | ||||
| 	current_token.kind := TOKEN_BOOLEAN | ||||
| 	current_token.kind := TOKEN_BOOLEAN; | ||||
| 	current_token.value.boolean_value := false | ||||
|   elsif "nil" = token_content then | ||||
| 	current_token.kind := TOKEN_NIL | ||||
| @@ -708,7 +708,7 @@ begin | ||||
|   elsif "defer" = token_content then | ||||
| 	current_token.kind := TOKEN_DEFER | ||||
|   else | ||||
| 	current_token.kind := TOKEN_IDENTIFIER | ||||
| 	current_token.kind := TOKEN_IDENTIFIER; | ||||
| 	current_token.value.string := string_dup(token_content) | ||||
|   end | ||||
|  | ||||
| @@ -721,39 +721,39 @@ var | ||||
|   first_char: Char | ||||
|   token_buffer: StringBuffer | ||||
| begin | ||||
|   tokens_size^ := 0u | ||||
|   tokens := nil | ||||
|   token_buffer := string_buffer_new() | ||||
|   tokens_size^ := 0u; | ||||
|   tokens := nil; | ||||
|   token_buffer := string_buffer_new(); | ||||
|  | ||||
|   skip_spaces(@source_code) | ||||
|   skip_spaces(@source_code); | ||||
|  | ||||
|   while not source_code_empty(@source_code) do | ||||
| 	tokens := cast(reallocarray(cast(tokens: ^Byte), tokens_size^ + 1u, #size(Token)): ^Token) | ||||
|     current_token := tokens + tokens_size^ | ||||
| 	first_char := source_code_head(source_code) | ||||
| 	tokens := cast(reallocarray(cast(tokens: ^Byte), tokens_size^ + 1u, #size(Token)): ^Token); | ||||
|     current_token := tokens + tokens_size^; | ||||
| 	first_char := source_code_head(source_code); | ||||
|  | ||||
|     if is_alpha(first_char) or first_char = '_' then | ||||
|       lex_identifier(@source_code, @token_buffer) | ||||
|       lex_identifier(@source_code, @token_buffer); | ||||
|       current_token^ := categorize_identifier(string_buffer_clear(@token_buffer)) | ||||
| 	elsif is_digit(first_char) then | ||||
| 	  lex_number(@source_code, @current_token^.value.int_value) | ||||
| 	  lex_number(@source_code, @current_token^.value.int_value); | ||||
|  | ||||
| 	  if source_code_expect(@source_code, 'u') then | ||||
| 	    current_token^.kind := TOKEN_WORD | ||||
| 	    current_token^.kind := TOKEN_WORD; | ||||
|         source_code_advance(@source_code) | ||||
| 	  else | ||||
| 	    current_token^.kind := TOKEN_INTEGER | ||||
| 	  end | ||||
| 	elsif first_char = '(' then | ||||
| 	  source_code_advance(@source_code) | ||||
| 	  source_code_advance(@source_code); | ||||
|  | ||||
| 	  if source_code_empty(@source_code) then | ||||
| 	    current_token^.kind := TOKEN_LEFT_PAREN | ||||
| 	  elsif source_code_head(source_code) = '*' then | ||||
| 	    source_code_advance(@source_code) | ||||
| 	    source_code_advance(@source_code); | ||||
|  | ||||
| 		if lex_comment(@source_code, @token_buffer) then | ||||
| 	      current_token^.value.string := string_dup(string_buffer_clear(@token_buffer)) | ||||
| 	      current_token^.value.string := string_dup(string_buffer_clear(@token_buffer)); | ||||
| 		  current_token^.kind := TOKEN_COMMENT | ||||
| 		else | ||||
| 	      current_token^.kind := 0 | ||||
| @@ -762,129 +762,129 @@ begin | ||||
| 	    current_token^.kind := TOKEN_LEFT_PAREN | ||||
| 	  end | ||||
| 	elsif first_char = ')' then | ||||
| 	  current_token^.kind := TOKEN_RIGHT_PAREN | ||||
| 	  current_token^.kind := TOKEN_RIGHT_PAREN; | ||||
| 	  source_code_advance(@source_code) | ||||
| 	elsif first_char = '\'' then | ||||
|       source_code_advance(@source_code) | ||||
|       source_code_advance(@source_code); | ||||
|  | ||||
| 	  if lex_character(@source_code, @current_token^.value.char_value) and source_code_expect(@source_code, '\'') then | ||||
| 	  	current_token^.kind := TOKEN_CHARACTER | ||||
| 	  	current_token^.kind := TOKEN_CHARACTER; | ||||
| 	    source_code_advance(@source_code) | ||||
| 	  else | ||||
| 	    current_token^.kind := 0 | ||||
| 	  end | ||||
| 	elsif first_char = '"' then | ||||
|       source_code_advance(@source_code) | ||||
|       source_code_advance(@source_code); | ||||
| 	   | ||||
|       if lex_string(@source_code, @token_buffer) then | ||||
| 		current_token^.kind := TOKEN_STRING | ||||
| 		current_token^.kind := TOKEN_STRING; | ||||
| 		current_token^.value.string := string_dup(string_buffer_clear(@token_buffer)) | ||||
| 	  else | ||||
| 	    current_token^.kind := 0 | ||||
| 	  end | ||||
| 	elsif first_char = '[' then | ||||
| 	  current_token^.kind := TOKEN_LEFT_SQUARE | ||||
| 	  current_token^.kind := TOKEN_LEFT_SQUARE; | ||||
| 	  source_code_advance(@source_code) | ||||
| 	elsif first_char = ']' then | ||||
| 	  current_token^.kind := TOKEN_RIGHT_SQUARE | ||||
| 	  current_token^.kind := TOKEN_RIGHT_SQUARE; | ||||
| 	  source_code_advance(@source_code) | ||||
| 	elsif first_char = '>' then | ||||
| 	  source_code_advance(@source_code) | ||||
| 	  source_code_advance(@source_code); | ||||
|  | ||||
|       if source_code_empty(@source_code) then | ||||
| 	    current_token^.kind := TOKEN_GREATER_THAN | ||||
| 	  elsif source_code_head(source_code) = '=' then | ||||
| 	    current_token^.kind := TOKEN_GREATER_EQUAL | ||||
| 	    current_token^.kind := TOKEN_GREATER_EQUAL; | ||||
| 	    source_code_advance(@source_code) | ||||
| 	  elsif source_code_head(source_code) = '>' then | ||||
| 	    current_token^.kind := TOKEN_SHIFT_RIGHT | ||||
| 	    current_token^.kind := TOKEN_SHIFT_RIGHT; | ||||
| 	    source_code_advance(@source_code) | ||||
| 	  else | ||||
| 	    current_token^.kind := TOKEN_GREATER_THAN | ||||
| 	  end | ||||
| 	elsif first_char = '<' then | ||||
| 	  source_code_advance(@source_code) | ||||
| 	  source_code_advance(@source_code); | ||||
|  | ||||
| 	  if source_code_empty(@source_code) then | ||||
| 	    current_token^.kind := TOKEN_LESS_THAN | ||||
| 	  elsif source_code_head(source_code) = '=' then | ||||
| 	    current_token^.kind := TOKEN_LESS_EQUAL | ||||
| 	    current_token^.kind := TOKEN_LESS_EQUAL; | ||||
| 	    source_code_advance(@source_code) | ||||
| 	  elsif source_code_head(source_code) = '<' then | ||||
| 	    current_token^.kind := TOKEN_SHIFT_LEFT | ||||
| 	    current_token^.kind := TOKEN_SHIFT_LEFT; | ||||
| 	    source_code_advance(@source_code) | ||||
| 	  elsif source_code_head(source_code) = '>' then | ||||
| 	    current_token^.kind := TOKEN_NOT_EQUAL | ||||
| 	    current_token^.kind := TOKEN_NOT_EQUAL; | ||||
| 	    source_code_advance(@source_code) | ||||
| 	  else | ||||
| 	    current_token^.kind := TOKEN_LESS_THAN | ||||
| 	  end | ||||
| 	elsif first_char = '=' then | ||||
| 	  current_token^.kind := TOKEN_EQUAL | ||||
| 	  current_token^.kind := TOKEN_EQUAL; | ||||
| 	  source_code_advance(@source_code) | ||||
| 	elsif first_char = ';' then | ||||
| 	  current_token^.kind := TOKEN_SEMICOLON | ||||
| 	  current_token^.kind := TOKEN_SEMICOLON; | ||||
| 	  source_code_advance(@source_code) | ||||
| 	elsif first_char = '.' then | ||||
| 	  current_token^.kind := TOKEN_DOT | ||||
| 	  current_token^.kind := TOKEN_DOT; | ||||
| 	  source_code_advance(@source_code) | ||||
| 	elsif first_char = ',' then | ||||
| 	  current_token^.kind := TOKEN_COMMA | ||||
| 	  current_token^.kind := TOKEN_COMMA; | ||||
| 	  source_code_advance(@source_code) | ||||
| 	elsif first_char = '+' then | ||||
| 	  current_token^.kind := TOKEN_PLUS | ||||
| 	  current_token^.kind := TOKEN_PLUS; | ||||
| 	  source_code_advance(@source_code) | ||||
| 	elsif first_char = '-' then | ||||
| 	  source_code_advance(@source_code) | ||||
| 	  source_code_advance(@source_code); | ||||
|  | ||||
|       if source_code_empty(@source_code) then | ||||
| 	    current_token^.kind := TOKEN_MINUS | ||||
| 	  elsif source_code_head(source_code) = '>' then | ||||
| 	    current_token^.kind := TOKEN_ARROW | ||||
| 	    current_token^.kind := TOKEN_ARROW; | ||||
| 	    source_code_advance(@source_code) | ||||
| 	  else | ||||
| 	    current_token^.kind := TOKEN_MINUS | ||||
| 	  end | ||||
| 	elsif first_char = '*' then | ||||
| 	  current_token^.kind := TOKEN_MULTIPLICATION | ||||
| 	  current_token^.kind := TOKEN_MULTIPLICATION; | ||||
| 	  source_code_advance(@source_code) | ||||
| 	elsif first_char = '/' then | ||||
| 	  current_token^.kind := TOKEN_DIVISION | ||||
| 	  current_token^.kind := TOKEN_DIVISION; | ||||
| 	  source_code_advance(@source_code) | ||||
| 	elsif first_char = '%' then | ||||
| 	  current_token^.kind := TOKEN_REMAINDER | ||||
| 	  current_token^.kind := TOKEN_REMAINDER; | ||||
| 	  source_code_advance(@source_code) | ||||
| 	elsif first_char = ':' then | ||||
| 	  source_code_advance(@source_code) | ||||
| 	  source_code_advance(@source_code); | ||||
|  | ||||
| 	  if source_code_empty(@source_code) then | ||||
| 	    current_token^.kind := TOKEN_COLON | ||||
| 	  elsif source_code_head(source_code) = '=' then | ||||
| 	    current_token^.kind := TOKEN_ASSIGNMENT | ||||
| 	    current_token^.kind := TOKEN_ASSIGNMENT; | ||||
| 	    source_code_advance(@source_code) | ||||
| 	  else | ||||
| 	    current_token^.kind := TOKEN_COLON | ||||
| 	  end | ||||
| 	elsif first_char = '^' then | ||||
| 	  current_token^.kind := TOKEN_HAT | ||||
| 	  current_token^.kind := TOKEN_HAT; | ||||
| 	  source_code_advance(@source_code) | ||||
| 	elsif first_char = '@' then | ||||
| 	  current_token^.kind := TOKEN_AT | ||||
| 	  current_token^.kind := TOKEN_AT; | ||||
| 	  source_code_advance(@source_code) | ||||
| 	elsif first_char = '!' then | ||||
| 	  current_token^.kind := TOKEN_EXCLAMATION | ||||
| 	  current_token^.kind := TOKEN_EXCLAMATION; | ||||
| 	  source_code_advance(@source_code) | ||||
| 	else | ||||
| 	  current_token^.kind := 0 | ||||
| 	  current_token^.kind := 0; | ||||
| 	  source_code_advance(@source_code) | ||||
| 	end | ||||
| 	end; | ||||
|  | ||||
| 	if current_token^.kind <> 0 then | ||||
|       tokens_size^ := tokens_size^ + 1u | ||||
|       tokens_size^ := tokens_size^ + 1u; | ||||
|       skip_spaces(@source_code) | ||||
| 	else | ||||
| 	  write_s("Lexical analysis error on \"") | ||||
| 	  write_c(first_char) | ||||
| 	  write_s("Lexical analysis error on \""); | ||||
| 	  write_c(first_char); | ||||
| 	  write_s("\".\n") | ||||
| 	end | ||||
|   end | ||||
| @@ -898,14 +898,14 @@ var | ||||
|   i: Int | ||||
|   result: ^CommandLine | ||||
| begin | ||||
|   i := 1 | ||||
|   result := cast(malloc(#size(CommandLine)): ^CommandLine) | ||||
|   result^.tokenize := false | ||||
|   result^.syntax_tree := false | ||||
|   result^.input := nil | ||||
|   i := 1; | ||||
|   result := cast(malloc(#size(CommandLine)): ^CommandLine); | ||||
|   result^.tokenize := false; | ||||
|   result^.syntax_tree := false; | ||||
|   result^.input := nil; | ||||
|  | ||||
|   while i < argc and result <> nil do | ||||
|     parameter := argv + i | ||||
|     parameter := argv + i; | ||||
|  | ||||
|     if strcmp(parameter^, "--tokenize\0".ptr) = 0 then | ||||
|       result^.tokenize := true | ||||
| @@ -914,19 +914,19 @@ begin | ||||
|     elsif parameter^^ <> '-' then | ||||
|       result^.input := parameter^ | ||||
|     else | ||||
|       write_s("Fatal error: Unknown command line options:") | ||||
|       write_s("Fatal error: Unknown command line options:"); | ||||
|  | ||||
|       write_c(' ') | ||||
|       write_z(parameter^) | ||||
|       write_s(".\n") | ||||
|       write_c(' '); | ||||
|       write_z(parameter^); | ||||
|       write_s(".\n"); | ||||
|  | ||||
|       result := nil | ||||
|     end | ||||
|     end; | ||||
|  | ||||
|     i := i + 1 | ||||
|   end | ||||
|   end; | ||||
|   if result <> nil and result^.input = nil then | ||||
|     write_s("Fatal error: no input files.\n") | ||||
|     write_s("Fatal error: no input files.\n"); | ||||
| 	result := nil | ||||
|   end | ||||
|  | ||||
| @@ -941,30 +941,30 @@ var | ||||
|   command_line: ^CommandLine | ||||
|   return_code: Int | ||||
| begin | ||||
|   return_code := 0 | ||||
|   return_code := 0; | ||||
|  | ||||
|   command_line := parse_command_line(argc, argv) | ||||
|   command_line := parse_command_line(argc, argv); | ||||
|   if command_line = nil then | ||||
|     return_code := 2 | ||||
|   end | ||||
|   end; | ||||
|  | ||||
|   if return_code = 0 then | ||||
| 	source_code.position := make_position() | ||||
| 	source_code.position := make_position(); | ||||
|  | ||||
| 	source_code.input := cast(read_source(command_line^.input): ^Byte) | ||||
| 	source_code.empty := source_file_empty | ||||
| 	source_code.head := source_file_head | ||||
| 	source_code.advance := source_file_advance | ||||
| 	source_code.input := cast(read_source(command_line^.input): ^Byte); | ||||
| 	source_code.empty := source_file_empty; | ||||
| 	source_code.head := source_file_head; | ||||
| 	source_code.advance := source_file_advance; | ||||
|  | ||||
| 	if source_code.input = nil then | ||||
|       perror(command_line^.input) | ||||
|       perror(command_line^.input); | ||||
|       return_code := 3 | ||||
| 	end | ||||
|   end | ||||
|   end; | ||||
|   if return_code = 0 then | ||||
|     tokens := tokenize(source_code, @tokens_size) | ||||
|     tokens := tokenize(source_code, @tokens_size); | ||||
|  | ||||
|     fclose(cast(source_code.input: ^SourceFile)^.handle) | ||||
|     fclose(cast(source_code.input: ^SourceFile)^.handle); | ||||
|  | ||||
|     if command_line^.tokenize then | ||||
|       print_tokens(tokens, tokens_size) | ||||
|   | ||||
		Reference in New Issue
	
	Block a user