Use colon instead of as to cast
This commit is contained in:
22
README.md
22
README.md
@ -21,3 +21,25 @@ and a possbility to compile Elna programs for different platforms.
|
||||
|
||||
Flex and bison grammar specifications, `lexer.ll` and `parser.yy`, can be found
|
||||
in the `boot/` directory.
|
||||
|
||||
## Build
|
||||
|
||||
The frontend requires GCC 14.2.0 (not tested with other versions).
|
||||
|
||||
Download the GCC source. Copy the contents of this repository into `gcc/elna`
|
||||
inside GCC. Finally build GCC enabling the frontend with
|
||||
`--enable-languages=c,c++,elna`. After the installation the compiler can be
|
||||
invoked with `$prefix/bin/gelna`.
|
||||
|
||||
There is also a `Rakefile` that downloads, builds and installs GCC into the
|
||||
`./build/` subdirectory. The `Rakefile` assumes that ruby and rake, as well as
|
||||
all GCC dependencies are already available in the system. It works under Linux
|
||||
and Mac OS. In the latter case GCC is patched with the patches used by Homebrew
|
||||
(official GCC doesn't support Apple silicon targets). Invoke with
|
||||
|
||||
```sh
|
||||
rake boot
|
||||
```
|
||||
|
||||
See `rake -T` for more tasks. The GCC source is under `build/tools`. The
|
||||
installation path is `build/host/install`.
|
||||
|
@ -134,9 +134,6 @@ return {
|
||||
cast {
|
||||
return yy::parser::make_CAST(this->location);
|
||||
}
|
||||
as {
|
||||
return yy::parser::make_AS(this->location);
|
||||
}
|
||||
sizeof {
|
||||
return yy::parser::make_SIZEOF(this->location);
|
||||
}
|
||||
|
@ -85,7 +85,7 @@ along with GCC; see the file COPYING3. If not see
|
||||
%token CONST VAR PROCEDURE ARRAY OF 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 AS SIZEOF
|
||||
%token AND OR NOT CAST SIZEOF
|
||||
%token GREATER_EQUAL LESS_EQUAL LESS_THAN GREATER_THAN NOT_EQUAL EQUALS
|
||||
%token PLUS MINUS MULTIPLICATION DIVISION REMAINDER
|
||||
%token ASSIGNMENT COLON HAT AT NIL ARROW
|
||||
@ -189,7 +189,7 @@ call_expression: IDENTIFIER actual_parameter_list
|
||||
$$ = new elna::boot::call_expression(elna::boot::make_position(@1), $1);
|
||||
std::swap($$->arguments(), $2);
|
||||
}
|
||||
cast_expression: CAST LEFT_PAREN expression AS type_expression RIGHT_PAREN
|
||||
cast_expression: CAST LEFT_PAREN expression COLON type_expression RIGHT_PAREN
|
||||
{
|
||||
$$ = new elna::boot::cast_expression(elna::boot::make_position(@1), $5, $3);
|
||||
}
|
||||
@ -403,9 +403,9 @@ optional_statements:
|
||||
field_declaration:
|
||||
IDENTIFIER COLON type_expression { $$ = std::make_pair($1, $3); }
|
||||
field_list:
|
||||
field_declaration SEMICOLON field_list
|
||||
field_declaration field_list
|
||||
{
|
||||
std::swap($$, $3);
|
||||
std::swap($$, $2);
|
||||
$$.emplace($$.cbegin(), $1);
|
||||
}
|
||||
| field_declaration { $$.emplace_back($1); }
|
||||
|
@ -43,6 +43,94 @@ namespace gcc
|
||||
this->symbol_map = symbol_table;
|
||||
}
|
||||
|
||||
void generic_visitor::build_procedure_call(location_t call_location,
|
||||
tree symbol, const std::vector<boot::expression *>& arguments)
|
||||
{
|
||||
vec<tree, va_gc> *argument_trees = nullptr;
|
||||
tree current_parameter = TYPE_ARG_TYPES(TREE_TYPE(symbol));
|
||||
|
||||
vec_alloc(argument_trees, arguments.size());
|
||||
for (boot::expression *const argument : arguments)
|
||||
{
|
||||
location_t argument_location = get_location(&argument->position());
|
||||
if (is_void_type(TREE_VALUE(current_parameter)))
|
||||
{
|
||||
error_at(argument_location, "too many arguments, expected %i, got %lu",
|
||||
list_length(TYPE_ARG_TYPES(TREE_TYPE(symbol))) - 1, arguments.size());
|
||||
this->current_expression = error_mark_node;
|
||||
break;
|
||||
}
|
||||
argument->accept(this);
|
||||
if (!is_assignable_from(TREE_VALUE(current_parameter), this->current_expression))
|
||||
{
|
||||
error_at(argument_location,
|
||||
"cannot assign value of type '%s' to variable of type '%s'",
|
||||
print_type(TREE_TYPE(this->current_expression)).c_str(),
|
||||
print_type(TREE_VALUE(current_parameter)).c_str());
|
||||
this->current_expression = error_mark_node;
|
||||
}
|
||||
current_parameter = TREE_CHAIN(current_parameter);
|
||||
argument_trees->quick_push(this->current_expression);
|
||||
}
|
||||
tree stmt = build_call_expr_loc_vec(call_location, symbol, argument_trees);
|
||||
|
||||
if (!is_void_type(TREE_VALUE(current_parameter)))
|
||||
{
|
||||
error_at(call_location, "too few arguments, expected %i, got %lu",
|
||||
list_length(TYPE_ARG_TYPES(TREE_TYPE(symbol))) - 1, arguments.size());
|
||||
this->current_expression = error_mark_node;
|
||||
}
|
||||
else if (TREE_TYPE(TREE_TYPE(symbol)) == void_type_node)
|
||||
{
|
||||
append_statement(stmt);
|
||||
this->current_expression = NULL_TREE;
|
||||
}
|
||||
else
|
||||
{
|
||||
this->current_expression = stmt;
|
||||
}
|
||||
}
|
||||
|
||||
void generic_visitor::build_record_call(location_t call_location,
|
||||
tree symbol, const std::vector<boot::expression *>& arguments)
|
||||
{
|
||||
vec<constructor_elt, va_gc> *tree_arguments = nullptr;
|
||||
tree record_fields = TYPE_FIELDS(symbol);
|
||||
for (boot::expression *const argument : arguments)
|
||||
{
|
||||
location_t argument_location = get_location(&argument->position());
|
||||
|
||||
if (is_void_type(record_fields))
|
||||
{
|
||||
error_at(argument_location, "too many arguments, expected %i, got %lu",
|
||||
list_length(TYPE_FIELDS(symbol)), arguments.size());
|
||||
this->current_expression = error_mark_node;
|
||||
break;
|
||||
}
|
||||
argument->accept(this);
|
||||
if (!is_assignable_from(TREE_TYPE(record_fields), this->current_expression))
|
||||
{
|
||||
error_at(argument_location,
|
||||
"cannot assign value of type '%s' to variable of type '%s'",
|
||||
print_type(TREE_TYPE(this->current_expression)).c_str(),
|
||||
print_type(TREE_TYPE(record_fields)).c_str());
|
||||
this->current_expression = error_mark_node;
|
||||
}
|
||||
CONSTRUCTOR_APPEND_ELT(tree_arguments, record_fields, this->current_expression);
|
||||
record_fields = TREE_CHAIN(record_fields);
|
||||
}
|
||||
if (!is_void_type(record_fields))
|
||||
{
|
||||
error_at(call_location, "too few arguments, expected %i, got %lu",
|
||||
list_length(TYPE_FIELDS(symbol)), arguments.size());
|
||||
this->current_expression = error_mark_node;
|
||||
}
|
||||
else
|
||||
{
|
||||
this->current_expression = build_constructor(symbol, tree_arguments);
|
||||
}
|
||||
}
|
||||
|
||||
void generic_visitor::visit(boot::call_expression *expression)
|
||||
{
|
||||
tree symbol = this->lookup(expression->name());
|
||||
@ -56,37 +144,11 @@ namespace gcc
|
||||
}
|
||||
else if (DECL_P(symbol) && is_procedure_type(TREE_TYPE(symbol)))
|
||||
{
|
||||
vec<tree, va_gc> *arguments = nullptr;
|
||||
|
||||
vec_alloc(arguments, expression->arguments().size());
|
||||
for (boot::expression *const argument : expression->arguments())
|
||||
{
|
||||
argument->accept(this);
|
||||
arguments->quick_push(this->current_expression);
|
||||
}
|
||||
tree stmt = build_call_expr_loc_vec(get_location(&expression->position()), symbol, arguments);
|
||||
|
||||
if (TREE_TYPE(TREE_TYPE(symbol)) == void_type_node)
|
||||
{
|
||||
append_statement(stmt);
|
||||
this->current_expression = NULL_TREE;
|
||||
}
|
||||
else
|
||||
{
|
||||
this->current_expression = stmt;
|
||||
}
|
||||
build_procedure_call(call_location, symbol, expression->arguments());
|
||||
}
|
||||
else if (TYPE_P(symbol) && is_record_type(symbol))
|
||||
{
|
||||
vec<constructor_elt, va_gc> *arguments = nullptr;
|
||||
tree record_fields = TYPE_FIELDS(symbol);
|
||||
for (boot::expression *const argument : expression->arguments())
|
||||
{
|
||||
argument->accept(this);
|
||||
CONSTRUCTOR_APPEND_ELT(arguments, record_fields, this->current_expression);
|
||||
record_fields = TREE_CHAIN(record_fields);
|
||||
}
|
||||
this->current_expression = build_constructor(symbol, arguments);
|
||||
build_record_call(call_location, symbol, expression->arguments());
|
||||
}
|
||||
else
|
||||
{
|
||||
@ -475,7 +537,9 @@ namespace gcc
|
||||
}
|
||||
return;
|
||||
}
|
||||
if (left_type != right_type && !are_compatible_pointers(left, right) && !are_compatible_pointers(right, left))
|
||||
if (left_type != right_type
|
||||
&& !are_compatible_pointers(left_type, right)
|
||||
&& !are_compatible_pointers(right_type, left))
|
||||
{
|
||||
error_at(expression_location,
|
||||
"invalid operands of type %s and %s for operator %s",
|
||||
@ -848,8 +912,7 @@ namespace gcc
|
||||
this->current_expression = error_mark_node;
|
||||
return;
|
||||
}
|
||||
if (TREE_TYPE(this->current_expression) == TREE_TYPE(lvalue)
|
||||
|| are_compatible_pointers(lvalue, this->current_expression))
|
||||
if (is_assignable_from(TREE_TYPE(lvalue), this->current_expression))
|
||||
{
|
||||
tree assignment = build2_loc(statement_location, MODIFY_EXPR,
|
||||
void_type_node, lvalue, this->current_expression);
|
||||
|
@ -67,15 +67,21 @@ namespace gcc
|
||||
return TREE_CODE(type) == RECORD_TYPE;
|
||||
}
|
||||
|
||||
bool are_compatible_pointers(tree lhs, tree rhs)
|
||||
bool are_compatible_pointers(tree lhs_type, tree rhs)
|
||||
{
|
||||
tree lhs_type = TREE_TYPE(lhs);
|
||||
gcc_assert(TYPE_P(lhs_type));
|
||||
tree rhs_type = TREE_TYPE(rhs);
|
||||
|
||||
return (is_pointer_type(lhs_type) && rhs == elna_pointer_nil_node)
|
||||
|| (is_pointer_type(lhs_type) && lhs_type == rhs_type);
|
||||
}
|
||||
|
||||
bool is_assignable_from(tree assignee, tree assignment)
|
||||
{
|
||||
return TREE_TYPE(assignment) == assignee
|
||||
|| are_compatible_pointers(assignee, assignment);
|
||||
}
|
||||
|
||||
void append_statement(tree statement_tree)
|
||||
{
|
||||
if (!vec_safe_is_empty(f_binding_level->defers))
|
||||
|
@ -56,6 +56,10 @@ namespace gcc
|
||||
tree build_logic_operation(boot::binary_expression *expression,
|
||||
tree_code operator_code, tree left, tree right);
|
||||
tree build_equality_operation(boot::binary_expression *expression, tree left, tree right);
|
||||
void build_procedure_call(location_t call_location,
|
||||
tree symbol, const std::vector<boot::expression *>& arguments);
|
||||
void build_record_call(location_t call_location,
|
||||
tree symbol, const std::vector<boot::expression *>& arguments);
|
||||
|
||||
public:
|
||||
generic_visitor(std::shared_ptr<boot::symbol_table<tree>> symbol_table);
|
||||
|
@ -46,7 +46,14 @@ namespace gcc
|
||||
* \param rhs Right hand value.
|
||||
* \return Whether rhs can be assigned to lhs.
|
||||
*/
|
||||
bool are_compatible_pointers(tree lhs, tree rhs);
|
||||
bool are_compatible_pointers(tree lhs_type, tree rhs);
|
||||
|
||||
/**
|
||||
* \param assignee Assignee.
|
||||
* \param assignee Assignment.
|
||||
* \return Whether an expression assignment can be assigned to a variable of type assignee.
|
||||
*/
|
||||
bool is_assignable_from(tree assignee, tree assignment);
|
||||
|
||||
void append_statement(tree statement_tree);
|
||||
void defer(tree statement_tree);
|
||||
|
91
source.elna
91
source.elna
@ -63,46 +63,46 @@ const
|
||||
|
||||
type
|
||||
Position* = record
|
||||
line: Word;
|
||||
line: Word
|
||||
column: Word
|
||||
end
|
||||
Location* = record
|
||||
first: Position;
|
||||
first: Position
|
||||
last: Position
|
||||
end
|
||||
SourceCode = record
|
||||
position: Position;
|
||||
position: Position
|
||||
text: String
|
||||
end
|
||||
TokenValue* = union
|
||||
int_value: Int;
|
||||
string_value: pointer to Char;
|
||||
string: String;
|
||||
boolean_value: Bool;
|
||||
int_value: Int
|
||||
string_value: pointer to Char
|
||||
string: String
|
||||
boolean_value: Bool
|
||||
char_value: Char
|
||||
end
|
||||
Token* = record
|
||||
kind: Int;
|
||||
value: TokenValue;
|
||||
kind: Int
|
||||
value: TokenValue
|
||||
location: Location
|
||||
end
|
||||
FILE* = record
|
||||
dummy: Int
|
||||
end
|
||||
CommandLine* = record
|
||||
input: pointer to Char;
|
||||
tokenize: Bool;
|
||||
input: pointer to Char
|
||||
tokenize: Bool
|
||||
syntax_tree: Bool
|
||||
end
|
||||
Literal* = record
|
||||
value: Int
|
||||
end
|
||||
ConstantDefinition* = record
|
||||
name: pointer to Char;
|
||||
name: pointer to Char
|
||||
body: pointer to Literal
|
||||
end
|
||||
ConstantPart* = record
|
||||
elements: pointer to pointer to ConstantDefinition;
|
||||
elements: pointer to pointer to ConstantDefinition
|
||||
count: Word
|
||||
end
|
||||
Program* = record
|
||||
@ -148,12 +148,12 @@ end
|
||||
|
||||
proc write_s(value: String);
|
||||
begin
|
||||
write(0, value.ptr, value.length)
|
||||
write(0, cast(value.ptr: pointer to Byte), cast(value.length: Int))
|
||||
end
|
||||
|
||||
proc write_z(value: pointer to Char);
|
||||
begin
|
||||
write(0, value, strlen(value))
|
||||
write(0, cast(value: pointer to Byte), cast(strlen(value): Int))
|
||||
end
|
||||
|
||||
proc write_b(value: Bool);
|
||||
@ -167,7 +167,7 @@ end
|
||||
|
||||
proc write_c(value: Char);
|
||||
begin
|
||||
write(0, @value, 1)
|
||||
write(0, cast(@value: pointer to Byte), 1)
|
||||
end
|
||||
|
||||
proc write_i(value: Int);
|
||||
@ -184,7 +184,7 @@ begin
|
||||
digit := value % 10;
|
||||
value := value / 10;
|
||||
|
||||
buffer[n] := cast(cast('0' as Int) + digit as Char);
|
||||
buffer[n] := cast(cast('0': Int) + digit: Char);
|
||||
n := n - 1u
|
||||
end;
|
||||
while n < 10u do
|
||||
@ -195,17 +195,17 @@ end
|
||||
|
||||
proc write_u(value: Word);
|
||||
begin
|
||||
write_i(value)
|
||||
write_i(cast(value: Int))
|
||||
end
|
||||
|
||||
proc is_digit(c: Char) -> Bool;
|
||||
begin
|
||||
return cast(c as Int) >= cast('0' as Int) and cast(c as Int) <= cast('9' as Int)
|
||||
return cast(c: Int) >= cast('0': Int) and cast(c: Int) <= cast('9': Int)
|
||||
end
|
||||
|
||||
proc is_alpha(c: Char) -> Bool;
|
||||
begin
|
||||
return cast(c as Int) >= cast('A' as Int) and cast(c as Int) <= cast('z' as Int)
|
||||
return cast(c: Int) >= cast('A': Int) and cast(c: Int) <= cast('z': Int)
|
||||
end
|
||||
|
||||
proc is_alnum(c: Char) -> Bool;
|
||||
@ -232,7 +232,7 @@ proc string_dup(origin: String) -> String;
|
||||
var
|
||||
copy: pointer to Char;
|
||||
begin
|
||||
copy := cast(malloc(origin.length) as pointer to Char);
|
||||
copy := cast(malloc(origin.length): pointer to Char);
|
||||
strncpy(copy, origin.ptr, origin.length);
|
||||
|
||||
return String(copy, origin.length)
|
||||
@ -246,9 +246,7 @@ proc make_position() -> Position;
|
||||
var
|
||||
result: Position;
|
||||
begin
|
||||
result.line := 1u;
|
||||
result.column := 1u;
|
||||
return result
|
||||
return Position(1u, 1u)
|
||||
end
|
||||
|
||||
proc read_source(filename: pointer to Char, result: pointer to String) -> Bool;
|
||||
@ -274,12 +272,12 @@ begin
|
||||
end;
|
||||
rewind(input_file);
|
||||
|
||||
input := malloc(source_size);
|
||||
if fread(input, source_size, 1, input_file) <> 1u then
|
||||
input := malloc(cast(source_size: Word));
|
||||
if fread(input, cast(source_size: Word), 1u, input_file) <> 1u then
|
||||
return false
|
||||
end;
|
||||
result^.length := cast(source_size as Word);
|
||||
result^.ptr := cast(input as pointer to Char);
|
||||
result^.length := cast(source_size: Word);
|
||||
result^.ptr := cast(input: pointer to Char);
|
||||
|
||||
return true
|
||||
end
|
||||
@ -373,12 +371,12 @@ begin
|
||||
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^, 0, content_length);
|
||||
token_content^ := substring(token_content^, 0u, content_length);
|
||||
|
||||
return true
|
||||
end;
|
||||
content_length := content_length + 1u;
|
||||
source_code^ := advance_source(source_code^, 1)
|
||||
source_code^ := advance_source(source_code^, 1u)
|
||||
end;
|
||||
|
||||
return false
|
||||
@ -413,8 +411,8 @@ begin
|
||||
if token_end^ <> '\"' then
|
||||
return input
|
||||
end;
|
||||
token_length := cast(token_end - input as Word);
|
||||
current_token^.value.string_value := cast(calloc(token_length, 1) as pointer to Char);
|
||||
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;
|
||||
@ -565,7 +563,7 @@ begin
|
||||
write_s("u>")
|
||||
elsif current_token^.kind = TOKEN_CHARACTER then
|
||||
write_c('<');
|
||||
write_i(current_token^.value.char_value);
|
||||
write_i(cast(current_token^.value.char_value: Int));
|
||||
write_s("c>")
|
||||
elsif current_token^.kind = TOKEN_STRING then
|
||||
write_s("\"...\"")
|
||||
@ -671,7 +669,7 @@ begin
|
||||
source_code := skip_spaces(source_code);
|
||||
|
||||
while source_code.text.length <> 0u do
|
||||
tokens := cast(reallocarray(tokens, tokens_size^ + 1u, sizeof(Token)) as pointer to Token);
|
||||
tokens := cast(reallocarray(cast(tokens: pointer to Byte), tokens_size^ + 1u, sizeof(Token)): pointer to Token);
|
||||
current_token := tokens + tokens_size^;
|
||||
first_char := source_code.text[1u];
|
||||
|
||||
@ -681,7 +679,7 @@ begin
|
||||
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 as Word);
|
||||
token_length := cast(token_end - source_code.text.ptr: Word);
|
||||
|
||||
if token_end^ = 'u' then
|
||||
current_token^.kind := TOKEN_WORD;
|
||||
@ -712,7 +710,7 @@ begin
|
||||
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 as Word);
|
||||
token_length := cast(token_end - source_code.text.ptr: Word);
|
||||
|
||||
if token_end^ = '\'' then
|
||||
current_token^.kind := TOKEN_CHARACTER;
|
||||
@ -725,7 +723,7 @@ begin
|
||||
|
||||
if token_end^ = '"' then
|
||||
current_token^.kind := TOKEN_STRING;
|
||||
token_length := cast(token_end - source_code.text.ptr as Word);
|
||||
token_length := cast(token_end - source_code.text.ptr: Word);
|
||||
source_code := advance_source(source_code, token_length + 1u)
|
||||
end
|
||||
elsif first_char = '[' then
|
||||
@ -823,7 +821,7 @@ 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)
|
||||
return cast(calloc(1u, sizeof(Literal)): pointer to Literal)
|
||||
end
|
||||
|
||||
proc parse_constant_definition(tokens: pointer to pointer to Token,
|
||||
@ -831,9 +829,9 @@ proc parse_constant_definition(tokens: pointer to pointer to Token,
|
||||
var
|
||||
result: pointer to ConstantDefinition;
|
||||
begin
|
||||
result := cast(calloc(1, sizeof(ConstantDefinition)) as pointer to ConstantDefinition);
|
||||
result := cast(calloc(1u, sizeof(ConstantDefinition)): pointer to ConstantDefinition);
|
||||
|
||||
result^.name := cast(malloc(strlen(tokens^^.value.string_value)) as pointer to Char);
|
||||
result^.name := cast(malloc(strlen(tokens^^.value.string_value)): pointer to Char);
|
||||
strcpy(result^.name, tokens^^.value.string_value);
|
||||
|
||||
tokens^ := tokens^ + 2u;
|
||||
@ -855,7 +853,7 @@ var
|
||||
result: pointer to Program,
|
||||
current_constant: pointer to pointer to ConstantDefinition;
|
||||
begin
|
||||
result := cast(calloc(1, sizeof(Program)) as pointer to Program);
|
||||
result := cast(calloc(1u, sizeof(Program)): pointer to Program);
|
||||
|
||||
result^.constants.elements := nil;
|
||||
result^.constants.count := 0u;
|
||||
@ -866,8 +864,11 @@ begin
|
||||
|
||||
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);
|
||||
reallocarray(
|
||||
cast(result^.constants.elements: pointer to Byte),
|
||||
result^.constants.count + 1u,
|
||||
sizeof(pointer to ConstantDefinition)
|
||||
) : pointer to pointer to ConstantDefinition);
|
||||
current_constant := result^.constants.elements + result^.constants.count;
|
||||
|
||||
result^.constants.count := result^.constants.count + 1u;
|
||||
@ -887,7 +888,7 @@ var
|
||||
result: pointer to CommandLine;
|
||||
begin
|
||||
i := 1;
|
||||
result := cast(malloc(sizeof(CommandLine)) as pointer to CommandLine);
|
||||
result := cast(malloc(sizeof(CommandLine)): pointer to CommandLine);
|
||||
result^.tokenize := false;
|
||||
result^.syntax_tree := false;
|
||||
result^.input := nil;
|
||||
@ -950,5 +951,5 @@ begin
|
||||
end
|
||||
|
||||
begin
|
||||
exit(process(count, parameters))
|
||||
exit(process(cast(count: Int), cast(parameters: pointer to pointer to Char)))
|
||||
end.
|
||||
|
Reference in New Issue
Block a user