Implement .max and .min type properties
This commit is contained in:
		| @@ -89,12 +89,6 @@ const                   { | ||||
| var                     { | ||||
|                             return yy::parser::make_VAR(this->location); | ||||
|                         } | ||||
| array                   { | ||||
|                             return yy::parser::make_ARRAY(this->location); | ||||
|                         } | ||||
| of                      { | ||||
|                             return yy::parser::make_OF(this->location); | ||||
|                         } | ||||
| type                    { | ||||
|                             return yy::parser::make_TYPE(this->location); | ||||
|                         } | ||||
|   | ||||
| @@ -82,7 +82,7 @@ along with GCC; see the file COPYING3.  If not see | ||||
| %token <std::string> STRING "string" | ||||
| %token <bool> BOOLEAN | ||||
| %token IF WHILE DO THEN ELSE ELSIF RETURN | ||||
| %token CONST VAR PROCEDURE ARRAY OF TYPE RECORD POINTER TO UNION | ||||
| %token CONST VAR PROCEDURE TYPE RECORD POINTER TO UNION | ||||
| %token BEGIN_BLOCK END_BLOCK EXTERN DEFER | ||||
| %token LEFT_PAREN RIGHT_PAREN LEFT_SQUARE RIGHT_SQUARE SEMICOLON DOT COMMA | ||||
| %token AND OR NOT CAST SHIFT_LEFT SHIFT_RIGHT | ||||
| @@ -414,9 +414,9 @@ statement: | ||||
|         } | ||||
|     | defer_statement { $$ = $1; } | ||||
| statements: | ||||
|     statement SEMICOLON statements | ||||
|     statement statements | ||||
|         { | ||||
|             std::swap($$, $3); | ||||
|             std::swap($$, $2); | ||||
|             $$.emplace($$.cbegin(), $1); | ||||
|         } | ||||
|     | statement { $$.push_back($1); } | ||||
| @@ -433,7 +433,7 @@ field_list: | ||||
|         } | ||||
|     | field_declaration { $$.emplace_back($1); } | ||||
| type_expression: | ||||
|     ARRAY INTEGER OF type_expression | ||||
|     LEFT_SQUARE INTEGER RIGHT_SQUARE type_expression | ||||
|         { | ||||
|             $$ = std::make_shared<elna::boot::array_type>(elna::boot::make_position(@1), $4, $2); | ||||
|         } | ||||
|   | ||||
| @@ -952,6 +952,14 @@ namespace gcc | ||||
|                 this->current_expression = build_int_cstu(elna_word_type_node, | ||||
|                         TYPE_ALIGN_UNIT(this->current_expression)); | ||||
|             } | ||||
|             else if (expression->field() == "min" && is_integral_type(this->current_expression)) | ||||
|             { | ||||
|                 this->current_expression = TYPE_MIN_VALUE(this->current_expression); | ||||
|             } | ||||
|             else if (expression->field() == "max" && is_integral_type(this->current_expression)) | ||||
|             { | ||||
|                 this->current_expression =  TYPE_MAX_VALUE(this->current_expression); | ||||
|             } | ||||
|             else | ||||
|             { | ||||
|                 error_at(expression_location, "type '%s' does not have property '%s'", | ||||
|   | ||||
							
								
								
									
										348
									
								
								source.elna
									
									
									
									
									
								
							
							
						
						
									
										348
									
								
								source.elna
									
									
									
									
									
								
							| @@ -174,22 +174,22 @@ proc write_i(value: Int); | ||||
| var | ||||
|   digit: Int | ||||
|   n: Word | ||||
|   buffer: array 10 of Char | ||||
|   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 | ||||
| @@ -233,8 +233,8 @@ proc string_dup(origin: String) -> String; | ||||
| var | ||||
|   copy: pointer to Char | ||||
| begin | ||||
|   copy := cast(malloc(origin.length): pointer to Char); | ||||
|   strncpy(copy, origin.ptr, origin.length); | ||||
|   copy := cast(malloc(origin.length): pointer to Char) | ||||
|   strncpy(copy, origin.ptr, origin.length) | ||||
|  | ||||
|   return String(copy, origin.length) | ||||
| end | ||||
| @@ -254,28 +254,28 @@ var | ||||
|   source_size: Int | ||||
|   input: pointer to Byte | ||||
| begin | ||||
|   input_file := fopen(filename, "rb\0".ptr); | ||||
|   input_file := fopen(filename, "rb\0".ptr) | ||||
|  | ||||
|   if input_file = nil then | ||||
|     return false | ||||
|   end; | ||||
|   end | ||||
|   defer | ||||
|     fclose(input_file) | ||||
|   end; | ||||
|   end | ||||
|   if fseek(input_file, 0, SEEK_END) <> 0 then | ||||
|     return false | ||||
|   end; | ||||
|   source_size := ftell(input_file); | ||||
|   end | ||||
|   source_size := ftell(input_file) | ||||
|   if source_size < 0 then | ||||
|     return false | ||||
|   end; | ||||
|   rewind(input_file); | ||||
|   end | ||||
|   rewind(input_file) | ||||
|  | ||||
|   input := malloc(cast(source_size: Word)); | ||||
|   input := malloc(cast(source_size: Word)) | ||||
|   if fread(input, cast(source_size: Word), 1u, input_file) <> 1u then | ||||
|     return false | ||||
|   end; | ||||
|   result^ := String(cast(input: pointer to Char), cast(source_size: Word)); | ||||
|   end | ||||
|   result^ := String(cast(input: pointer to Char), cast(source_size: Word)) | ||||
|  | ||||
|   return true | ||||
| end | ||||
| @@ -283,40 +283,40 @@ end | ||||
| proc escape_char(escape: Char, result: pointer to Char) -> Bool; | ||||
| begin | ||||
|   if escape = 'n' then | ||||
| 	result^ := '\n'; | ||||
| 	result^ := '\n' | ||||
| 	return true | ||||
|   elsif escape = 'a' then | ||||
| 	result^ := '\a'; | ||||
| 	result^ := '\a' | ||||
| 	return true | ||||
|   elsif escape = 'b' then | ||||
| 	result^ := '\b'; | ||||
| 	result^ := '\b' | ||||
| 	return true | ||||
|   elsif escape = 't' then | ||||
| 	result^ := '\t'; | ||||
| 	result^ := '\t' | ||||
| 	return true | ||||
|   elsif escape = 'f' then | ||||
| 	result^ := '\f'; | ||||
| 	result^ := '\f' | ||||
| 	return true | ||||
|   elsif escape = 'r' then | ||||
| 	result^ := '\r'; | ||||
| 	result^ := '\r' | ||||
| 	return true | ||||
|   elsif escape = 'v' then | ||||
| 	result^ := '\v'; | ||||
| 	result^ := '\v' | ||||
| 	return true | ||||
|   elsif escape = '\\' then | ||||
| 	result^ := '\\'; | ||||
| 	result^ := '\\' | ||||
| 	return true | ||||
|   elsif escape = '\'' then | ||||
| 	result^ := '\''; | ||||
| 	result^ := '\'' | ||||
| 	return true | ||||
|   elsif escape = '"' then | ||||
| 	result^ := '"'; | ||||
| 	result^ := '"' | ||||
| 	return true | ||||
|   elsif escape = '?' then | ||||
| 	result^ := '\?'; | ||||
| 	result^ := '\?' | ||||
| 	return true | ||||
|   elsif escape = '0' then | ||||
| 	result^ := '\0'; | ||||
| 	result^ := '\0' | ||||
| 	return true | ||||
|   else | ||||
| 	return false | ||||
| @@ -325,8 +325,8 @@ end | ||||
|  | ||||
| proc advance_source(source_code: SourceCode, length: Word) -> SourceCode; | ||||
| begin | ||||
|   source_code.text := open_substring(source_code.text, length); | ||||
|   source_code.position.column := source_code.position.column + length; | ||||
|   source_code.text := open_substring(source_code.text, length) | ||||
|   source_code.position.column := source_code.position.column + length | ||||
|  | ||||
|   return source_code | ||||
| end | ||||
| @@ -335,13 +335,13 @@ proc skip_spaces(source_code: SourceCode) -> SourceCode; | ||||
| begin | ||||
|   while source_code.text.length > 0u and is_space(source_code.text[1u]) do | ||||
|     if source_code.text[1u] = '\n' then | ||||
|       source_code.position.line := source_code.position.line + 1u; | ||||
|       source_code.position.line := source_code.position.line + 1u | ||||
|       source_code.position.column := 1u | ||||
| 	else | ||||
| 	  source_code.position.column := source_code.position.column + 1u | ||||
| 	end; | ||||
| 	end | ||||
|     source_code.text := open_substring(source_code.text, 1u) | ||||
|   end; | ||||
|   end | ||||
|   return source_code | ||||
| end | ||||
|  | ||||
| @@ -349,13 +349,13 @@ proc lex_identifier(source_code: pointer to SourceCode, token_content: pointer t | ||||
| var | ||||
|   content_length: Word | ||||
| begin | ||||
|   content_length := 0u; | ||||
|   token_content^ := source_code^.text; | ||||
|   content_length := 0u | ||||
|   token_content^ := source_code^.text | ||||
|  | ||||
|   while is_alnum(source_code^.text[1u]) or source_code^.text[1u] = '_' do | ||||
|     content_length := content_length + 1u; | ||||
|     content_length := content_length + 1u | ||||
| 	source_code^ := advance_source(source_code^, 1u) | ||||
|   end; | ||||
|   end | ||||
|   token_content^ := substring(token_content^, 0u, content_length) | ||||
| end | ||||
|  | ||||
| @@ -363,19 +363,19 @@ proc lex_comment(source_code: pointer to SourceCode, token_content: pointer to S | ||||
| var | ||||
|   content_length: Word | ||||
| begin | ||||
|   content_length := 0u; | ||||
|   token_content^ := source_code^.text; | ||||
|   content_length := 0u | ||||
|   token_content^ := source_code^.text | ||||
|  | ||||
|   while source_code^.text.length > 1u do | ||||
|     if source_code^.text[1u] = '*' and source_code^.text[2u] = ')' then | ||||
| 	  source_code^ := advance_source(source_code^, 2u); | ||||
| 	  token_content^ := substring(token_content^, 0u, content_length); | ||||
| 	  source_code^ := advance_source(source_code^, 2u) | ||||
| 	  token_content^ := substring(token_content^, 0u, content_length) | ||||
|  | ||||
| 	  return true | ||||
| 	end; | ||||
|     content_length := content_length + 1u; | ||||
| 	end | ||||
|     content_length := content_length + 1u | ||||
| 	source_code^ := advance_source(source_code^, 1u) | ||||
|   end; | ||||
|   end | ||||
|  | ||||
|   return false | ||||
| end | ||||
| @@ -383,14 +383,14 @@ end | ||||
| proc lex_character(input: pointer to Char, current_token: pointer to Token) -> pointer to Char; | ||||
| begin | ||||
|   if input^ = '\\' then | ||||
|     input := input + 1; | ||||
|     input := input + 1 | ||||
| 	if escape_char(input^, @current_token^.value.char_value) then | ||||
| 	  input := input + 1 | ||||
| 	end | ||||
|   elsif input^ <> '\0' then | ||||
|     current_token^.value.char_value := input^; | ||||
|     current_token^.value.char_value := input^ | ||||
| 	input := input + 1 | ||||
|   end; | ||||
|   end | ||||
|   return input | ||||
| end | ||||
|  | ||||
| @@ -400,35 +400,35 @@ var | ||||
|   token_length: Word | ||||
|   is_valid: Bool | ||||
| begin | ||||
|   token_end := input; | ||||
|   token_end := input | ||||
|  | ||||
|   while token_end^ <> '\0' and not ((token_end - 1)^ <> '\\' and token_end^ = '"') do | ||||
|     token_end := token_end + 1 | ||||
|   end; | ||||
|   end | ||||
|   if token_end^ <> '\"' then | ||||
|     return input | ||||
|   end; | ||||
|   token_length := cast(token_end - input: Word); | ||||
|   current_token^.value.string_value := cast(calloc(token_length, 1u): pointer to Char); | ||||
|   end | ||||
|   token_length := cast(token_end - input: Word) | ||||
|   current_token^.value.string_value := cast(calloc(token_length, 1u): pointer to Char) | ||||
|  | ||||
|   is_valid := true; | ||||
|   constructed_string := current_token^.value.string_value; | ||||
|   is_valid := true | ||||
|   constructed_string := current_token^.value.string_value | ||||
|   while input < token_end and is_valid do | ||||
|  | ||||
|     if input^ = '\\' then | ||||
|       input := input + 1; | ||||
|       input := input + 1 | ||||
|       if escape_char(input^, constructed_string) then | ||||
|         input := input + 1 | ||||
| 	  else | ||||
| 	    is_valid := false | ||||
|       end | ||||
|     elsif input^ <> '\0' then | ||||
|       constructed_string^ := input^; | ||||
|       constructed_string^ := input^ | ||||
|       input := input + 1 | ||||
|     end; | ||||
|     end | ||||
|  | ||||
|     constructed_string := constructed_string + 1 | ||||
|   end; | ||||
|   end | ||||
|  | ||||
|   return token_end | ||||
| end | ||||
| @@ -438,9 +438,9 @@ var | ||||
|   current_token: pointer to 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") | ||||
| @@ -481,8 +481,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") | ||||
| @@ -501,8 +501,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("(") | ||||
| @@ -551,30 +551,30 @@ 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("\"...\"") | ||||
| 	elsif current_token^.kind = TOKEN_DEFER then | ||||
| 	  write_s("DEFER") | ||||
| 	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; | ||||
|   end | ||||
|   write_c('\n') | ||||
| end | ||||
|  | ||||
| @@ -621,10 +621,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 | ||||
| @@ -641,9 +641,9 @@ 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; | ||||
|   end | ||||
|  | ||||
|   return current_token | ||||
| end | ||||
| @@ -656,40 +656,40 @@ var | ||||
|   first_char: Char | ||||
|   token_content: String | ||||
| begin | ||||
|   tokens_size^ := 0u; | ||||
|   tokens := nil; | ||||
|   source_code := skip_spaces(source_code); | ||||
|   tokens_size^ := 0u | ||||
|   tokens := nil | ||||
|   source_code := skip_spaces(source_code) | ||||
|  | ||||
|   while source_code.text.length <> 0u do | ||||
| 	tokens := cast(reallocarray(cast(tokens: pointer to Byte), tokens_size^ + 1u, Token.size): pointer to Token); | ||||
|     current_token := tokens + tokens_size^; | ||||
| 	first_char := source_code.text[1u]; | ||||
| 	tokens := cast(reallocarray(cast(tokens: pointer to Byte), tokens_size^ + 1u, Token.size): pointer to Token) | ||||
|     current_token := tokens + tokens_size^ | ||||
| 	first_char := source_code.text[1u] | ||||
|  | ||||
|     if is_alpha(first_char) or first_char = '_' then | ||||
|       lex_identifier(@source_code, @token_content); | ||||
|       lex_identifier(@source_code, @token_content) | ||||
|       current_token^ := categorize_identifier(token_content) | ||||
| 	elsif is_digit(first_char) then | ||||
| 	  token_end := nil; | ||||
| 	  current_token^.value.int_value := strtol(source_code.text.ptr, @token_end, 10); | ||||
| 	  token_length := cast(token_end - source_code.text.ptr: Word); | ||||
| 	  token_end := nil | ||||
| 	  current_token^.value.int_value := strtol(source_code.text.ptr, @token_end, 10) | ||||
| 	  token_length := cast(token_end - source_code.text.ptr: Word) | ||||
|  | ||||
| 	  if token_end^ = 'u' then | ||||
| 	    current_token^.kind := TOKEN_WORD; | ||||
| 	    current_token^.kind := TOKEN_WORD | ||||
|         source_code := advance_source(source_code, token_length + 1u) | ||||
| 	  else | ||||
| 	    current_token^.kind := TOKEN_INTEGER; | ||||
| 	    current_token^.kind := TOKEN_INTEGER | ||||
|         source_code := advance_source(source_code, token_length) | ||||
| 	  end | ||||
| 	elsif first_char = '(' then | ||||
| 	  source_code := advance_source(source_code, 1u); | ||||
| 	  source_code := advance_source(source_code, 1u) | ||||
|  | ||||
| 	  if source_code.text.length = 0u then | ||||
| 	    current_token^.kind := TOKEN_LEFT_PAREN | ||||
| 	  elsif source_code.text[1u] = '*' then | ||||
| 	    source_code := advance_source(source_code, 1u); | ||||
| 	    source_code := advance_source(source_code, 1u) | ||||
|  | ||||
| 		if lex_comment(@source_code, @token_content) then | ||||
| 	      current_token^.value.string := string_dup(token_content); | ||||
| 	      current_token^.value.string := string_dup(token_content) | ||||
| 		  current_token^.kind := TOKEN_COMMENT | ||||
| 		else | ||||
| 	      current_token^.kind := 0 | ||||
| @@ -698,121 +698,121 @@ 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(source_code, 1u) | ||||
| 	elsif first_char = '\'' then | ||||
| 	  token_end := lex_character(source_code.text.ptr + 1, current_token); | ||||
| 	  token_length := cast(token_end - source_code.text.ptr: Word); | ||||
| 	  token_end := lex_character(source_code.text.ptr + 1, current_token) | ||||
| 	  token_length := cast(token_end - source_code.text.ptr: Word) | ||||
|  | ||||
| 	  if token_end^ = '\'' then | ||||
| 	  	current_token^.kind := TOKEN_CHARACTER; | ||||
| 	  	current_token^.kind := TOKEN_CHARACTER | ||||
| 	    source_code := advance_source(source_code, token_length + 1u) | ||||
| 	  else | ||||
| 	    source_code := advance_source(source_code, 1u) | ||||
| 	  end | ||||
| 	elsif first_char = '"' then | ||||
| 	  token_end := lex_string(source_code.text.ptr + 1, current_token); | ||||
| 	  token_end := lex_string(source_code.text.ptr + 1, current_token) | ||||
|  | ||||
|       if token_end^ = '"' then | ||||
| 		current_token^.kind := TOKEN_STRING; | ||||
| 	    token_length := cast(token_end - source_code.text.ptr: Word); | ||||
| 		current_token^.kind := TOKEN_STRING | ||||
| 	    token_length := cast(token_end - source_code.text.ptr: Word) | ||||
| 	    source_code := advance_source(source_code, token_length + 1u) | ||||
| 	  end | ||||
| 	elsif first_char = '[' then | ||||
| 	  current_token^.kind := TOKEN_LEFT_SQUARE; | ||||
| 	  current_token^.kind := TOKEN_LEFT_SQUARE | ||||
| 	  source_code := advance_source(source_code, 1u) | ||||
| 	elsif first_char = ']' then | ||||
| 	  current_token^.kind := TOKEN_RIGHT_SQUARE; | ||||
| 	  current_token^.kind := TOKEN_RIGHT_SQUARE | ||||
| 	  source_code := advance_source(source_code, 1u) | ||||
| 	elsif first_char = '>' then | ||||
| 	  source_code := advance_source(source_code, 1u); | ||||
| 	  source_code := advance_source(source_code, 1u) | ||||
|  | ||||
|       if source_code.text.length = 0u then | ||||
| 	    current_token^.kind := TOKEN_GREATER_THAN | ||||
| 	  elsif source_code.text[1u] = '=' then | ||||
| 	    current_token^.kind := TOKEN_GREATER_EQUAL; | ||||
| 	    current_token^.kind := TOKEN_GREATER_EQUAL | ||||
| 	    source_code := advance_source(source_code, 1u) | ||||
| 	  elsif source_code.text[1u] = '>' then | ||||
| 	    current_token^.kind := TOKEN_SHIFT_RIGHT; | ||||
| 	    current_token^.kind := TOKEN_SHIFT_RIGHT | ||||
| 	    source_code := advance_source(source_code, 1u) | ||||
| 	  else | ||||
| 	    current_token^.kind := TOKEN_GREATER_THAN | ||||
| 	  end | ||||
| 	elsif first_char = '<' then | ||||
| 	  source_code := advance_source(source_code, 1u); | ||||
| 	  source_code := advance_source(source_code, 1u) | ||||
|  | ||||
| 	  if source_code.text.length = 0u then | ||||
| 	    current_token^.kind := TOKEN_LESS_THAN | ||||
| 	  elsif source_code.text[1u] = '=' then | ||||
| 	    current_token^.kind := TOKEN_LESS_EQUAL; | ||||
| 	    current_token^.kind := TOKEN_LESS_EQUAL | ||||
| 	    source_code := advance_source(source_code, 1u) | ||||
| 	  elsif source_code.text[1u] = '<' then | ||||
| 	    current_token^.kind := TOKEN_SHIFT_LEFT; | ||||
| 	    current_token^.kind := TOKEN_SHIFT_LEFT | ||||
| 	    source_code := advance_source(source_code, 1u) | ||||
| 	  elsif source_code.text[1u] = '>' then | ||||
| 	    current_token^.kind := TOKEN_NOT_EQUAL; | ||||
| 	    current_token^.kind := TOKEN_NOT_EQUAL | ||||
| 	    source_code := advance_source(source_code, 1u) | ||||
| 	  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(source_code, 1u) | ||||
| 	elsif first_char = ';' then | ||||
| 	  current_token^.kind := TOKEN_SEMICOLON; | ||||
| 	  current_token^.kind := TOKEN_SEMICOLON | ||||
| 	  source_code := advance_source(source_code, 1u) | ||||
| 	elsif first_char = '.' then | ||||
| 	  current_token^.kind := TOKEN_DOT; | ||||
| 	  current_token^.kind := TOKEN_DOT | ||||
| 	  source_code := advance_source(source_code, 1u) | ||||
| 	elsif first_char = ',' then | ||||
| 	  current_token^.kind := TOKEN_COMMA; | ||||
| 	  current_token^.kind := TOKEN_COMMA | ||||
| 	  source_code := advance_source(source_code, 1u) | ||||
| 	elsif first_char = '+' then | ||||
| 	  current_token^.kind := TOKEN_PLUS; | ||||
| 	  current_token^.kind := TOKEN_PLUS | ||||
| 	  source_code := advance_source(source_code, 1u) | ||||
| 	elsif first_char = '-' then | ||||
| 	  current_token^.kind := TOKEN_MINUS; | ||||
| 	  current_token^.kind := TOKEN_MINUS | ||||
| 	  source_code := advance_source(source_code, 1u) | ||||
| 	elsif first_char = '*' then | ||||
| 	  current_token^.kind := TOKEN_MULTIPLICATION; | ||||
| 	  current_token^.kind := TOKEN_MULTIPLICATION | ||||
| 	  source_code := advance_source(source_code, 1u) | ||||
| 	elsif first_char = '/' then | ||||
| 	  current_token^.kind := TOKEN_DIVISION; | ||||
| 	  current_token^.kind := TOKEN_DIVISION | ||||
| 	  source_code := advance_source(source_code, 1u) | ||||
| 	elsif first_char = '%' then | ||||
| 	  current_token^.kind := TOKEN_REMAINDER; | ||||
| 	  current_token^.kind := TOKEN_REMAINDER | ||||
| 	  source_code := advance_source(source_code, 1u) | ||||
| 	elsif first_char = ':' then | ||||
| 	  source_code := advance_source(source_code, 1u); | ||||
| 	  source_code := advance_source(source_code, 1u) | ||||
|  | ||||
| 	  if source_code.text.length = 0u then | ||||
| 	    current_token^.kind := TOKEN_COLON | ||||
| 	  elsif source_code.text[1u] = '=' then | ||||
| 	    current_token^.kind := TOKEN_ASSIGNMENT; | ||||
| 	    current_token^.kind := TOKEN_ASSIGNMENT | ||||
| 	    source_code := advance_source(source_code, 1u) | ||||
| 	  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(source_code, 1u) | ||||
| 	elsif first_char = '@' then | ||||
| 	  current_token^.kind := TOKEN_AT; | ||||
| 	  current_token^.kind := TOKEN_AT | ||||
| 	  source_code := advance_source(source_code, 1u) | ||||
| 	else | ||||
| 	  current_token^.kind := 0; | ||||
| 	  current_token^.kind := 0 | ||||
| 	  source_code := advance_source(source_code, 1u) | ||||
| 	end; | ||||
| 	end | ||||
|  | ||||
| 	if current_token^.kind <> 0 then | ||||
|       tokens_size^ := tokens_size^ + 1u; | ||||
|       tokens_size^ := tokens_size^ + 1u | ||||
|       source_code := 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; | ||||
|   end | ||||
|  | ||||
|   return tokens | ||||
| end | ||||
| @@ -827,21 +827,21 @@ proc parse_constant_definition(tokens: pointer to pointer to Token, | ||||
| var | ||||
|   result: pointer to ConstantDefinition | ||||
| begin | ||||
|   result := cast(calloc(1u, ConstantDefinition.size): pointer to ConstantDefinition); | ||||
|   result := cast(calloc(1u, ConstantDefinition.size): pointer to ConstantDefinition) | ||||
|  | ||||
|   result^.name := cast(malloc(strlen(tokens^^.value.string_value)): pointer to Char); | ||||
|   strcpy(result^.name, tokens^^.value.string_value); | ||||
|   result^.name := cast(malloc(strlen(tokens^^.value.string_value)): pointer to Char) | ||||
|   strcpy(result^.name, tokens^^.value.string_value) | ||||
|  | ||||
|   tokens^ := tokens^ + 2u; | ||||
|   tokens_size := tokens_size - 2u; | ||||
|   tokens^ := tokens^ + 2u | ||||
|   tokens_size := tokens_size - 2u | ||||
|  | ||||
|   write_z(result^.name); | ||||
|   write_c('\n'); | ||||
|   write_z(result^.name) | ||||
|   write_c('\n') | ||||
|  | ||||
|   result^.body := parse_literal(tokens, tokens_size); | ||||
|   result^.body := parse_literal(tokens, tokens_size) | ||||
|  | ||||
|   tokens^ := tokens^ + 2u; | ||||
|   tokens_size := tokens_size - 2u; | ||||
|   tokens^ := tokens^ + 2u | ||||
|   tokens_size := tokens_size - 2u | ||||
|  | ||||
|   return result | ||||
| end | ||||
| @@ -851,14 +851,14 @@ var | ||||
|   result: pointer to Program | ||||
|   current_constant: pointer to pointer to ConstantDefinition | ||||
| begin | ||||
|   result := cast(calloc(1u, Program.size): pointer to Program); | ||||
|   result := cast(calloc(1u, Program.size): pointer to Program) | ||||
|  | ||||
|   result^.constants.elements := nil; | ||||
|   result^.constants.count := 0u; | ||||
|   result^.constants.elements := nil | ||||
|   result^.constants.count := 0u | ||||
|  | ||||
|   if tokens^^.kind = TOKEN_CONST then | ||||
|     tokens^ := tokens^ + 1; | ||||
| 	tokens_size^ := tokens_size^ - 1u; | ||||
|     tokens^ := tokens^ + 1 | ||||
| 	tokens_size^ := tokens_size^ - 1u | ||||
|  | ||||
| 	while tokens_size^ > 0u and tokens^^.kind = TOKEN_IDENTIFIER do | ||||
| 	  result^.constants.elements := cast( | ||||
| @@ -866,12 +866,12 @@ begin | ||||
| 		  	cast(result^.constants.elements: pointer to Byte), | ||||
| 			result^.constants.count + 1u, | ||||
| 			(pointer to ConstantDefinition).size | ||||
| 		  ) : pointer to pointer to ConstantDefinition); | ||||
|       current_constant := result^.constants.elements + result^.constants.count; | ||||
| 		  ) : pointer to pointer to ConstantDefinition) | ||||
|       current_constant := result^.constants.elements + result^.constants.count | ||||
|  | ||||
| 	  result^.constants.count := result^.constants.count + 1u; | ||||
| 	  result^.constants.count := result^.constants.count + 1u | ||||
|  | ||||
| 	  current_constant^ := parse_constant_definition(tokens, tokens_size); | ||||
| 	  current_constant^ := parse_constant_definition(tokens, tokens_size) | ||||
| 	  if current_constant^ = nil then | ||||
| 	    return nil | ||||
| 	  end | ||||
| @@ -885,14 +885,14 @@ var | ||||
|   i: Int | ||||
|   result: pointer to CommandLine | ||||
| begin | ||||
|   i := 1; | ||||
|   result := cast(malloc(CommandLine.size): pointer to CommandLine); | ||||
|   result^.tokenize := false; | ||||
|   result^.syntax_tree := false; | ||||
|   result^.input := nil; | ||||
|   i := 1 | ||||
|   result := cast(malloc(CommandLine.size): pointer to CommandLine) | ||||
|   result^.tokenize := false | ||||
|   result^.syntax_tree := false | ||||
|   result^.input := nil | ||||
|  | ||||
|   while i < argc do | ||||
|     parameter := argv + i; | ||||
|     parameter := argv + i | ||||
|  | ||||
|     if strcmp(parameter^, "--tokenize\0".ptr) = 0 then | ||||
|       result^.tokenize := true | ||||
| @@ -901,21 +901,21 @@ 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") | ||||
|  | ||||
|       return nil | ||||
|     end; | ||||
|     end | ||||
|  | ||||
|     i := i + 1 | ||||
|   end; | ||||
|   end | ||||
|   if result^.input = nil then | ||||
|     write_s("Fatal error: no input files.\n"); | ||||
|     write_s("Fatal error: no input files.\n") | ||||
| 	return nil | ||||
|   end; | ||||
|   end | ||||
|  | ||||
|   return result | ||||
| end | ||||
| @@ -927,24 +927,24 @@ var | ||||
|   source_code: SourceCode | ||||
|   command_line: pointer to CommandLine | ||||
| begin | ||||
|   command_line := parse_command_line(argc, argv); | ||||
|   command_line := parse_command_line(argc, argv) | ||||
|   if command_line = nil then | ||||
|     return 2 | ||||
|   end; | ||||
|   end | ||||
|  | ||||
|   source_code.position := make_position(); | ||||
|   source_code.position := make_position() | ||||
|   if not read_source(command_line^.input, @source_code.text) then | ||||
|     perror(command_line^.input); | ||||
|     perror(command_line^.input) | ||||
| 	return 3 | ||||
|   end; | ||||
|   tokens := tokenize(source_code, @tokens_size); | ||||
|   end | ||||
|   tokens := tokenize(source_code, @tokens_size) | ||||
|  | ||||
|   if command_line^.tokenize then | ||||
|     print_tokens(tokens, tokens_size) | ||||
|   end; | ||||
|   end | ||||
|   if command_line^.syntax_tree then | ||||
|     parse_program(@tokens, @tokens_size) | ||||
|   end; | ||||
|   end | ||||
|   return 0 | ||||
| end | ||||
|  | ||||
|   | ||||
		Reference in New Issue
	
	Block a user