Pass 'basic_macro'
This commit is contained in:
parent
156fed3166
commit
ba80b65c3f
256
src/compiler.bbb
256
src/compiler.bbb
@ -1045,6 +1045,8 @@ Value = struct;
|
|||||||
Local = struct;
|
Local = struct;
|
||||||
Block = struct;
|
Block = struct;
|
||||||
Module = struct;
|
Module = struct;
|
||||||
|
MacroDeclaration = struct;
|
||||||
|
MacroInstantiation = struct;
|
||||||
|
|
||||||
ScopeKind = enum
|
ScopeKind = enum
|
||||||
{
|
{
|
||||||
@ -1779,7 +1781,7 @@ ValueId = enum
|
|||||||
variable,
|
variable,
|
||||||
local,
|
local,
|
||||||
unary_type,
|
unary_type,
|
||||||
macro_reference,
|
macro,
|
||||||
call,
|
call,
|
||||||
array_initialization,
|
array_initialization,
|
||||||
array_expression,
|
array_expression,
|
||||||
@ -1797,6 +1799,7 @@ ValueId = enum
|
|||||||
undefined,
|
undefined,
|
||||||
select,
|
select,
|
||||||
string_to_enum,
|
string_to_enum,
|
||||||
|
macro_instantiation,
|
||||||
}
|
}
|
||||||
|
|
||||||
ValueConstantInteger = struct
|
ValueConstantInteger = struct
|
||||||
@ -2023,6 +2026,41 @@ ValueStringToEnum = struct
|
|||||||
string: &Value,
|
string: &Value,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
ConstantArgumentId = enum
|
||||||
|
{
|
||||||
|
value,
|
||||||
|
type,
|
||||||
|
}
|
||||||
|
|
||||||
|
ConstantArgumentContent = union
|
||||||
|
{
|
||||||
|
value: &Value,
|
||||||
|
type: &Type,
|
||||||
|
}
|
||||||
|
|
||||||
|
ConstantArgument = struct
|
||||||
|
{
|
||||||
|
name: []u8,
|
||||||
|
content: ConstantArgumentContent,
|
||||||
|
id: ConstantArgumentId,
|
||||||
|
}
|
||||||
|
|
||||||
|
MacroInstantiation = struct
|
||||||
|
{
|
||||||
|
declaration: &MacroDeclaration,
|
||||||
|
instantiation_function: &Global,
|
||||||
|
declaration_arguments: []Argument,
|
||||||
|
instantiation_arguments: []&Value,
|
||||||
|
constant_arguments: []ConstantArgument,
|
||||||
|
return_type: &Type,
|
||||||
|
block: &Block,
|
||||||
|
scope: Scope,
|
||||||
|
line: u32,
|
||||||
|
column: u32,
|
||||||
|
return_alloca: &LLVMValue,
|
||||||
|
return_block: &LLVMBasicBlock,
|
||||||
|
}
|
||||||
|
|
||||||
ValueContent = union
|
ValueContent = union
|
||||||
{
|
{
|
||||||
constant_integer: ValueConstantInteger,
|
constant_integer: ValueConstantInteger,
|
||||||
@ -2042,6 +2080,8 @@ ValueContent = union
|
|||||||
aggregate_initialization: ValueAggregateInitialization,
|
aggregate_initialization: ValueAggregateInitialization,
|
||||||
select: ValueSelect,
|
select: ValueSelect,
|
||||||
string_to_enum: ValueStringToEnum,
|
string_to_enum: ValueStringToEnum,
|
||||||
|
macro: &MacroDeclaration,
|
||||||
|
macro_instantiation: MacroInstantiation,
|
||||||
}
|
}
|
||||||
|
|
||||||
ValueKind = enum
|
ValueKind = enum
|
||||||
@ -2126,12 +2166,18 @@ void_offset: u64 = i128_offset + 2;
|
|||||||
|
|
||||||
MacroDeclaration = struct
|
MacroDeclaration = struct
|
||||||
{
|
{
|
||||||
foo: u32,
|
arguments: []Argument,
|
||||||
|
constant_arguments: []ConstantArgument,
|
||||||
|
return_type: &Type,
|
||||||
|
block: &Block,
|
||||||
|
name: []u8,
|
||||||
|
scope: Scope,
|
||||||
|
next: &MacroDeclaration,
|
||||||
}
|
}
|
||||||
|
|
||||||
MacroInstantiation = struct
|
macro_declaration_is_generic = fn (declaration: &MacroDeclaration) u1
|
||||||
{
|
{
|
||||||
foo: u32,
|
return declaration.constant_arguments.length != 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
[extern] LLVMInitializeX86TargetInfo = fn [cc(c)] () void;
|
[extern] LLVMInitializeX86TargetInfo = fn [cc(c)] () void;
|
||||||
@ -4905,6 +4951,12 @@ tokenize = fn (module: &Module) Token
|
|||||||
|
|
||||||
parse_precedence = fn (module: &Module, scope: &Scope, builder: ValueBuilder) &Value;
|
parse_precedence = fn (module: &Module, scope: &Scope, builder: ValueBuilder) &Value;
|
||||||
|
|
||||||
|
scope_to_macro_declaration = fn (scope: &Scope) &MacroDeclaration
|
||||||
|
{
|
||||||
|
assert(scope.kind == .macro_declaration);
|
||||||
|
return #field_parent_pointer(scope, "scope");
|
||||||
|
}
|
||||||
|
|
||||||
reference_identifier = fn (module: &Module, current_scope: &Scope, identifier: []u8, kind: ValueKind) &Value
|
reference_identifier = fn (module: &Module, current_scope: &Scope, identifier: []u8, kind: ValueKind) &Value
|
||||||
{
|
{
|
||||||
assert(!string_equal(identifier, ""));
|
assert(!string_equal(identifier, ""));
|
||||||
@ -4936,9 +4988,22 @@ reference_identifier = fn (module: &Module, current_scope: &Scope, identifier: [
|
|||||||
|
|
||||||
>macro_declaration = module.first_macro_declaration;
|
>macro_declaration = module.first_macro_declaration;
|
||||||
|
|
||||||
while (macro_declaration != zero)
|
while (macro_declaration)
|
||||||
{
|
{
|
||||||
#trap();
|
if (string_equal(identifier, macro_declaration.name))
|
||||||
|
{
|
||||||
|
>result = new_value(module);
|
||||||
|
result.& = {
|
||||||
|
.content = {
|
||||||
|
.macro = macro_declaration,
|
||||||
|
},
|
||||||
|
.id = .macro,
|
||||||
|
zero,
|
||||||
|
};
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
macro_declaration = macro_declaration.next;
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
.function =>
|
.function =>
|
||||||
@ -4995,7 +5060,25 @@ reference_identifier = fn (module: &Module, current_scope: &Scope, identifier: [
|
|||||||
},
|
},
|
||||||
.macro_declaration =>
|
.macro_declaration =>
|
||||||
{
|
{
|
||||||
#trap();
|
assert(scope.parent != zero);
|
||||||
|
>macro_declaration = scope_to_macro_declaration(scope);
|
||||||
|
|
||||||
|
for (&constant_argument: macro_declaration.constant_arguments)
|
||||||
|
{
|
||||||
|
if (string_equal(identifier, constant_argument.name))
|
||||||
|
{
|
||||||
|
#trap();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
for (&argument: macro_declaration.arguments)
|
||||||
|
{
|
||||||
|
if (string_equal(identifier, argument.variable.name))
|
||||||
|
{
|
||||||
|
variable = &argument.variable;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
},
|
},
|
||||||
.macro_instantiation =>
|
.macro_instantiation =>
|
||||||
{
|
{
|
||||||
@ -5761,9 +5844,44 @@ parse_right = fn (module: &Module, scope: &Scope, builder: ValueBuilder) &Value
|
|||||||
|
|
||||||
switch (left.id)
|
switch (left.id)
|
||||||
{
|
{
|
||||||
.macro_reference =>
|
.macro =>
|
||||||
{
|
{
|
||||||
#trap();
|
>declaration = left.content.macro;
|
||||||
|
|
||||||
|
if (macro_declaration_is_generic(declaration))
|
||||||
|
{
|
||||||
|
report_error();
|
||||||
|
}
|
||||||
|
|
||||||
|
>instantiation_line = get_line(module);
|
||||||
|
>instantiation_column = get_column(module);
|
||||||
|
|
||||||
|
>arguments = parse_call_arguments(module, scope);
|
||||||
|
|
||||||
|
result.& = {
|
||||||
|
.content = {
|
||||||
|
.macro_instantiation = {
|
||||||
|
.declaration = declaration,
|
||||||
|
.instantiation_function = module.current_function,
|
||||||
|
.declaration_arguments = zero,
|
||||||
|
.instantiation_arguments = arguments,
|
||||||
|
.constant_arguments = zero,
|
||||||
|
.return_type = declaration.return_type,
|
||||||
|
.scope = {
|
||||||
|
.parent = scope,
|
||||||
|
.line = declaration.scope.line,
|
||||||
|
.column = declaration.scope.column,
|
||||||
|
.kind = .macro_instantiation,
|
||||||
|
zero,
|
||||||
|
},
|
||||||
|
.line = instantiation_line,
|
||||||
|
.column = instantiation_column,
|
||||||
|
zero,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
.id = .macro_instantiation,
|
||||||
|
zero,
|
||||||
|
};
|
||||||
},
|
},
|
||||||
else =>
|
else =>
|
||||||
{
|
{
|
||||||
@ -5789,7 +5907,7 @@ parse_right = fn (module: &Module, scope: &Scope, builder: ValueBuilder) &Value
|
|||||||
|
|
||||||
result = new_value(module);
|
result = new_value(module);
|
||||||
|
|
||||||
if (left.id == .macro_reference)
|
if (left.id == .macro)
|
||||||
{
|
{
|
||||||
#trap();
|
#trap();
|
||||||
}
|
}
|
||||||
@ -7016,7 +7134,118 @@ parse = fn (module: &Module) void
|
|||||||
},
|
},
|
||||||
.macro =>
|
.macro =>
|
||||||
{
|
{
|
||||||
#trap();
|
>constant_argument_buffer: [64]ConstantArgument = undefined;
|
||||||
|
>constant_argument_count: u64 = 0;
|
||||||
|
|
||||||
|
>is_generic = consume_character_if_match(module, left_bracket);
|
||||||
|
>macro_declaration = arena_allocate[MacroDeclaration](module.arena, 1);
|
||||||
|
macro_declaration.& = {
|
||||||
|
.name = global_name,
|
||||||
|
.scope = {
|
||||||
|
.parent = scope,
|
||||||
|
.line = global_line,
|
||||||
|
.column = global_column,
|
||||||
|
.kind = .macro_declaration,
|
||||||
|
zero,
|
||||||
|
},
|
||||||
|
zero,
|
||||||
|
};
|
||||||
|
|
||||||
|
if (is_generic)
|
||||||
|
{
|
||||||
|
// END OF SCOPE
|
||||||
|
if (constant_argument_count == 0)
|
||||||
|
{
|
||||||
|
report_error();
|
||||||
|
}
|
||||||
|
#trap();
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
assert(constant_argument_count == 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
expect_character(module, left_parenthesis);
|
||||||
|
|
||||||
|
macro_declaration.constant_arguments = arena_allocate_slice[ConstantArgument](module.arena, constant_argument_count);
|
||||||
|
memcpy(#pointer_cast(macro_declaration.constant_arguments.pointer), #pointer_cast(&constant_argument_buffer), constant_argument_count * #byte_size(ConstantArgument));
|
||||||
|
|
||||||
|
if (module.first_macro_declaration)
|
||||||
|
{
|
||||||
|
assert(module.first_macro_declaration != zero);
|
||||||
|
module.last_macro_declaration.next = macro_declaration;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
assert(!module.first_macro_declaration);
|
||||||
|
module.first_macro_declaration = macro_declaration;
|
||||||
|
}
|
||||||
|
|
||||||
|
module.last_macro_declaration = macro_declaration;
|
||||||
|
module.current_macro_declaration = macro_declaration;
|
||||||
|
|
||||||
|
>scope = ¯o_declaration.scope;
|
||||||
|
|
||||||
|
>argument_buffer: [64]Argument = undefined;
|
||||||
|
>argument_count: u64 = 0;
|
||||||
|
|
||||||
|
while (1)
|
||||||
|
{
|
||||||
|
skip_space(module);
|
||||||
|
|
||||||
|
if (consume_character_if_match(module, right_parenthesis))
|
||||||
|
{
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
>argument_index = argument_count;
|
||||||
|
|
||||||
|
>argument_line = get_line(module);
|
||||||
|
>argument_column = get_column(module);
|
||||||
|
|
||||||
|
>argument_name = arena_duplicate_string(module.arena, parse_identifier(module));
|
||||||
|
|
||||||
|
skip_space(module);
|
||||||
|
expect_character(module, ':');
|
||||||
|
skip_space(module);
|
||||||
|
|
||||||
|
>argument_type = parse_type(module, scope);
|
||||||
|
|
||||||
|
>argument = &argument_buffer[argument_index];
|
||||||
|
argument.& = {
|
||||||
|
.variable = {
|
||||||
|
.type = argument_type,
|
||||||
|
.scope = scope,
|
||||||
|
.name = argument_name,
|
||||||
|
.line = argument_line,
|
||||||
|
.column = argument_column,
|
||||||
|
zero,
|
||||||
|
},
|
||||||
|
.index = #truncate(argument_index + 1),
|
||||||
|
};
|
||||||
|
|
||||||
|
argument_count += 1;
|
||||||
|
|
||||||
|
skip_space(module);
|
||||||
|
consume_character_if_match(module, ',');
|
||||||
|
}
|
||||||
|
|
||||||
|
skip_space(module);
|
||||||
|
|
||||||
|
>return_type = parse_type(module, scope);
|
||||||
|
macro_declaration.return_type = return_type;
|
||||||
|
|
||||||
|
>arguments = arena_allocate_slice[Argument](module.arena, argument_count);
|
||||||
|
memcpy(#pointer_cast(arguments.pointer), #pointer_cast(&argument_buffer), argument_count * #byte_size(Argument));
|
||||||
|
macro_declaration.arguments = arguments;
|
||||||
|
|
||||||
|
skip_space(module);
|
||||||
|
|
||||||
|
>block = parse_block(module, scope);
|
||||||
|
macro_declaration.block = block;
|
||||||
|
|
||||||
|
// END OF SCOPE
|
||||||
|
module.current_macro_declaration = zero;
|
||||||
},
|
},
|
||||||
.opaque =>
|
.opaque =>
|
||||||
{
|
{
|
||||||
@ -10647,6 +10876,10 @@ analyze_type = fn (module: &Module, value: &Value, expected_type: &Type, analysi
|
|||||||
|
|
||||||
value_type = expected_type;
|
value_type = expected_type;
|
||||||
},
|
},
|
||||||
|
.macro_instantiation =>
|
||||||
|
{
|
||||||
|
#trap();
|
||||||
|
},
|
||||||
else =>
|
else =>
|
||||||
{
|
{
|
||||||
#trap();
|
#trap();
|
||||||
@ -16223,6 +16456,7 @@ names: [_][]u8 =
|
|||||||
"pointer_struct_initialization",
|
"pointer_struct_initialization",
|
||||||
"slice_array_literal",
|
"slice_array_literal",
|
||||||
"slice_only_start",
|
"slice_only_start",
|
||||||
|
"basic_macro",
|
||||||
];
|
];
|
||||||
|
|
||||||
[export] main = fn [cc(c)] (argument_count: u32, argv: &&u8, envp: &&u8) s32
|
[export] main = fn [cc(c)] (argument_count: u32, argv: &&u8, envp: &&u8) s32
|
||||||
|
@ -1029,7 +1029,6 @@ struct MacroDeclaration
|
|||||||
{
|
{
|
||||||
Slice<Argument> arguments;
|
Slice<Argument> arguments;
|
||||||
Slice<ConstantArgument> constant_arguments;
|
Slice<ConstantArgument> constant_arguments;
|
||||||
TypeList types;
|
|
||||||
Type* return_type;
|
Type* return_type;
|
||||||
Block* block;
|
Block* block;
|
||||||
String name;
|
String name;
|
||||||
|
Loading…
x
Reference in New Issue
Block a user