rework semantic analysis
This commit is contained in:
parent
b1ec34232f
commit
c75b8db371
File diff suppressed because it is too large
Load Diff
@ -324,6 +324,11 @@ extern "C" DISubprogram* NativityLLVMFunctionGetSubprogram(Function& function)
|
|||||||
return subprogram;
|
return subprogram;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
extern "C" void NativityLLVMGlobalVariableSetInitializer(GlobalVariable& global_variable, Constant* constant_initializer)
|
||||||
|
{
|
||||||
|
global_variable.setInitializer(constant_initializer);
|
||||||
|
}
|
||||||
|
|
||||||
extern "C" Constant* NativityLLVMConstantStruct(StructType* struct_type, Constant** constant_ptr, size_t constant_count)
|
extern "C" Constant* NativityLLVMConstantStruct(StructType* struct_type, Constant** constant_ptr, size_t constant_count)
|
||||||
{
|
{
|
||||||
auto constants = ArrayRef<Constant*>(constant_ptr, constant_count);
|
auto constants = ArrayRef<Constant*>(constant_ptr, constant_count);
|
||||||
|
File diff suppressed because it is too large
Load Diff
@ -116,3 +116,4 @@ pub extern fn NativityLLVMCreatePhiNode(type: *LLVM.Type, reserved_value_count:
|
|||||||
|
|
||||||
pub extern fn NativityLLVMAllocatGetAllocatedType(alloca: *LLVM.Value.Instruction.Alloca) *LLVM.Type;
|
pub extern fn NativityLLVMAllocatGetAllocatedType(alloca: *LLVM.Value.Instruction.Alloca) *LLVM.Type;
|
||||||
pub extern fn NativityLLVMValueToAlloca(value: *LLVM.Value) ?*LLVM.Value.Instruction.Alloca;
|
pub extern fn NativityLLVMValueToAlloca(value: *LLVM.Value) ?*LLVM.Value.Instruction.Alloca;
|
||||||
|
pub extern fn NativityLLVMGlobalVariableSetInitializer(global_variable: *LLVM.Value.Constant.GlobalVariable, constant_initializer: *LLVM.Value.Constant) void;
|
||||||
|
@ -13,7 +13,6 @@ const HashMap = data_structures.HashMap;
|
|||||||
const lexer = @import("lexer.zig");
|
const lexer = @import("lexer.zig");
|
||||||
|
|
||||||
const Compilation = @import("../Compilation.zig");
|
const Compilation = @import("../Compilation.zig");
|
||||||
const File = Compilation.File;
|
|
||||||
const log = Compilation.log;
|
const log = Compilation.log;
|
||||||
const logln = Compilation.logln;
|
const logln = Compilation.logln;
|
||||||
const Token = Compilation.Token;
|
const Token = Compilation.Token;
|
||||||
@ -179,10 +178,12 @@ pub const Node = struct {
|
|||||||
empty_container_literal_guess,
|
empty_container_literal_guess,
|
||||||
break_expression,
|
break_expression,
|
||||||
character_literal,
|
character_literal,
|
||||||
attribute_naked,
|
function_attribute_naked,
|
||||||
attribute_export,
|
function_attribute_cc,
|
||||||
attribute_extern,
|
symbol_attribute_extern,
|
||||||
attribute_cc,
|
symbol_attribute_export,
|
||||||
|
symbol_attributes,
|
||||||
|
metadata,
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -199,7 +200,6 @@ const Analyzer = struct {
|
|||||||
nodes: *Node.List,
|
nodes: *Node.List,
|
||||||
node_lists: *ArrayList(ArrayList(Node.Index)),
|
node_lists: *ArrayList(ArrayList(Node.Index)),
|
||||||
source_file: []const u8,
|
source_file: []const u8,
|
||||||
file_index: File.Index,
|
|
||||||
allocator: Allocator,
|
allocator: Allocator,
|
||||||
suffix_depth: usize = 0,
|
suffix_depth: usize = 0,
|
||||||
|
|
||||||
@ -288,10 +288,50 @@ const Analyzer = struct {
|
|||||||
|
|
||||||
logln(.parser, .symbol_declaration, "Current token: {}", .{analyzer.peekToken()});
|
logln(.parser, .symbol_declaration, "Current token: {}", .{analyzer.peekToken()});
|
||||||
|
|
||||||
const type_node_index = switch (analyzer.peekToken()) {
|
const metadata_node_index = switch (analyzer.peekToken()) {
|
||||||
.operator_colon => blk: {
|
.operator_colon => blk: {
|
||||||
analyzer.consumeToken();
|
const colon = try analyzer.expectToken(.operator_colon);
|
||||||
break :blk try analyzer.typeExpression();
|
const type_node_index = if (analyzer.peekToken() != .operator_colon) try analyzer.typeExpression() else .null;
|
||||||
|
const attribute_node_index: Node.Index = if (analyzer.peekToken() == .operator_colon) b: {
|
||||||
|
analyzer.consumeToken();
|
||||||
|
|
||||||
|
var list = ArrayList(Node.Index){};
|
||||||
|
while (analyzer.peekToken() != .operator_assign) {
|
||||||
|
const identifier = try analyzer.expectToken(.identifier);
|
||||||
|
const identifier_name = analyzer.bytes(identifier);
|
||||||
|
|
||||||
|
const attribute_node = inline for (@typeInfo(Compilation.Debug.Declaration.Global.Attribute).Enum.fields) |enum_field| {
|
||||||
|
if (equal(u8, identifier_name, enum_field.name)) {
|
||||||
|
const attribute = @field(Compilation.Debug.Declaration.Global.Attribute, enum_field.name);
|
||||||
|
const attribute_node = switch (attribute) {
|
||||||
|
.@"export" => try analyzer.addNode(.{
|
||||||
|
.id = @field(Node.Id, "symbol_attribute_" ++ @tagName(attribute)),
|
||||||
|
.token = identifier,
|
||||||
|
.left = .null,
|
||||||
|
.right = .null,
|
||||||
|
}),
|
||||||
|
};
|
||||||
|
break attribute_node;
|
||||||
|
}
|
||||||
|
} else @panic("Not known attribute");
|
||||||
|
try list.append(analyzer.allocator, attribute_node);
|
||||||
|
|
||||||
|
switch (analyzer.peekToken()) {
|
||||||
|
.operator_assign => {},
|
||||||
|
.operator_comma => analyzer.consumeToken(),
|
||||||
|
else => |t| @panic(@tagName(t)),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
break :b try analyzer.nodeList(list);
|
||||||
|
} else .null;
|
||||||
|
|
||||||
|
break :blk try analyzer.addNode(.{
|
||||||
|
.id = .metadata,
|
||||||
|
.token = colon,
|
||||||
|
.left = type_node_index,
|
||||||
|
.right = attribute_node_index,
|
||||||
|
});
|
||||||
},
|
},
|
||||||
else => Node.Index.null,
|
else => Node.Index.null,
|
||||||
};
|
};
|
||||||
@ -310,7 +350,7 @@ const Analyzer = struct {
|
|||||||
const declaration = Node{
|
const declaration = Node{
|
||||||
.id = mutability_node_id,
|
.id = mutability_node_id,
|
||||||
.token = first,
|
.token = first,
|
||||||
.left = type_node_index,
|
.left = metadata_node_index,
|
||||||
.right = init_node_index,
|
.right = init_node_index,
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -350,8 +390,8 @@ const Analyzer = struct {
|
|||||||
if (equal(u8, identifier_name, enum_field.name)) {
|
if (equal(u8, identifier_name, enum_field.name)) {
|
||||||
const attribute = @field(Compilation.Function.Attribute, enum_field.name);
|
const attribute = @field(Compilation.Function.Attribute, enum_field.name);
|
||||||
const attribute_node = switch (attribute) {
|
const attribute_node = switch (attribute) {
|
||||||
.naked, .@"export", => try analyzer.addNode(.{
|
.naked, => try analyzer.addNode(.{
|
||||||
.id = @field(Node.Id, "attribute_" ++ @tagName(attribute)),
|
.id = @field(Node.Id, "function_attribute_" ++ @tagName(attribute)),
|
||||||
.token = identifier,
|
.token = identifier,
|
||||||
.left = .null,
|
.left = .null,
|
||||||
.right = .null,
|
.right = .null,
|
||||||
@ -826,9 +866,9 @@ const Analyzer = struct {
|
|||||||
_ = try analyzer.expectToken(.operator_left_parenthesis);
|
_ = try analyzer.expectToken(.operator_left_parenthesis);
|
||||||
const intrinsic_name = analyzer.bytes(intrinsic_token)[1..];
|
const intrinsic_name = analyzer.bytes(intrinsic_token)[1..];
|
||||||
|
|
||||||
const intrinsic_id = inline for (@typeInfo(Compilation.Intrinsic.Id).Enum.fields) |enum_field| {
|
const intrinsic_id = inline for (@typeInfo(Compilation.IntrinsicId).Enum.fields) |enum_field| {
|
||||||
if (equal(u8, enum_field.name, intrinsic_name)) {
|
if (equal(u8, enum_field.name, intrinsic_name)) {
|
||||||
break @field(Compilation.Intrinsic.Id, enum_field.name);
|
break @field(Compilation.IntrinsicId, enum_field.name);
|
||||||
}
|
}
|
||||||
} else @panic(intrinsic_name);
|
} else @panic(intrinsic_name);
|
||||||
|
|
||||||
@ -1902,13 +1942,13 @@ const Analyzer = struct {
|
|||||||
|
|
||||||
fn addNode(analyzer: *Analyzer, node: Node) !Node.Index {
|
fn addNode(analyzer: *Analyzer, node: Node) !Node.Index {
|
||||||
const node_index = try analyzer.nodes.append(analyzer.allocator, node);
|
const node_index = try analyzer.nodes.append(analyzer.allocator, node);
|
||||||
logln(.parser, .node_creation, "Adding node #{} {s} to file #{} (left: {}, right: {})", .{ Node.unwrap(node_index), @tagName(node.id), File.unwrap(analyzer.file_index), switch (node.left) {
|
// logln(.parser, .node_creation, "Adding node #{} {s} to file #{} (left: {}, right: {})", .{ Node.unwrap(node_index), @tagName(node.id), File.unwrap(analyzer.file_index), switch (node.left) {
|
||||||
.null => 0xffff_ffff,
|
// .null => 0xffff_ffff,
|
||||||
else => Node.unwrap(node.left),
|
// else => Node.unwrap(node.left),
|
||||||
}, switch (node.right) {
|
// }, switch (node.right) {
|
||||||
.null => 0xffff_ffff,
|
// .null => 0xffff_ffff,
|
||||||
else => Node.unwrap(node.right),
|
// else => Node.unwrap(node.right),
|
||||||
}});
|
// }});
|
||||||
// if (Logger.bitset.contains(.node_creation_detailed)) {
|
// if (Logger.bitset.contains(.node_creation_detailed)) {
|
||||||
// const chunk_start = analyzer.lexer.offsets.items[node.token];
|
// const chunk_start = analyzer.lexer.offsets.items[node.token];
|
||||||
// const chunk_end = analyzer.lexer.offsets.items[node.token + 1];
|
// const chunk_end = analyzer.lexer.offsets.items[node.token + 1];
|
||||||
@ -1950,13 +1990,13 @@ const Analyzer = struct {
|
|||||||
|
|
||||||
|
|
||||||
// Here it is assumed that left brace is consumed
|
// Here it is assumed that left brace is consumed
|
||||||
pub fn analyze(allocator: Allocator, lexer_result: lexer.Result, source_file: []const u8, file_index: File.Index, token_buffer: *Token.Buffer, node_list: *Node.List, node_lists: *ArrayList(ArrayList(Node.Index))) !Result {
|
pub fn analyze(allocator: Allocator, lexer_result: lexer.Result, source_file: []const u8, token_buffer: *Token.Buffer, node_list: *Node.List, node_lists: *ArrayList(ArrayList(Node.Index))) !Result {
|
||||||
const start = std.time.Instant.now() catch unreachable;
|
const start = std.time.Instant.now() catch unreachable;
|
||||||
var analyzer = Analyzer{
|
var analyzer = Analyzer{
|
||||||
.lexer = lexer_result,
|
.lexer = lexer_result,
|
||||||
.token_buffer = token_buffer,
|
.token_buffer = token_buffer,
|
||||||
.source_file = source_file,
|
.source_file = source_file,
|
||||||
.file_index = file_index,
|
// .file_index = file_index,
|
||||||
.token_i = lexer_result.offset,
|
.token_i = lexer_result.offset,
|
||||||
.allocator = allocator,
|
.allocator = allocator,
|
||||||
.nodes = node_list,
|
.nodes = node_list,
|
||||||
|
@ -5,7 +5,6 @@ pub fn build(b: *std.Build) !void {
|
|||||||
const self_hosted_ci = b.option(bool, "self_hosted_ci", "This option enables the self-hosted CI behavior") orelse false;
|
const self_hosted_ci = b.option(bool, "self_hosted_ci", "This option enables the self-hosted CI behavior") orelse false;
|
||||||
const third_party_ci = b.option(bool, "third_party_ci", "This option enables the third-party CI behavior") orelse false;
|
const third_party_ci = b.option(bool, "third_party_ci", "This option enables the third-party CI behavior") orelse false;
|
||||||
const is_ci = self_hosted_ci or third_party_ci;
|
const is_ci = self_hosted_ci or third_party_ci;
|
||||||
_ = is_ci; // autofix
|
|
||||||
const native_target = b.resolveTargetQuery(.{});
|
const native_target = b.resolveTargetQuery(.{});
|
||||||
const optimization = b.standardOptimizeOption(.{});
|
const optimization = b.standardOptimizeOption(.{});
|
||||||
var target_query = b.standardTargetOptionsQueryOnly(.{});
|
var target_query = b.standardTargetOptionsQueryOnly(.{});
|
||||||
@ -76,9 +75,9 @@ pub fn build(b: *std.Build) !void {
|
|||||||
.target = target,
|
.target = target,
|
||||||
.optimize = optimization,
|
.optimize = optimization,
|
||||||
});
|
});
|
||||||
// compiler.formatted_panics = false;
|
compiler.formatted_panics = is_ci;
|
||||||
// compiler.root_module.unwind_tables = false;
|
compiler.root_module.unwind_tables = is_ci;
|
||||||
// compiler.root_module.omit_frame_pointer = false;
|
compiler.root_module.omit_frame_pointer = false;
|
||||||
compiler.want_lto = false;
|
compiler.want_lto = false;
|
||||||
|
|
||||||
compiler.linkLibC();
|
compiler.linkLibC();
|
||||||
|
@ -8,7 +8,7 @@ comptime {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
const _start = fn naked, export () noreturn {
|
const _start:: export = fn naked() noreturn {
|
||||||
#asm({
|
#asm({
|
||||||
xor ebp, ebp;
|
xor ebp, ebp;
|
||||||
mov rdi, rsp;
|
mov rdi, rsp;
|
||||||
@ -21,7 +21,7 @@ var argument_count: usize = 0;
|
|||||||
var argument_values: [&]const [&:0]const u8 = undefined;
|
var argument_values: [&]const [&:0]const u8 = undefined;
|
||||||
var environment_values: [&:null]const ?[&:null]const u8 = undefined;
|
var environment_values: [&:null]const ?[&:null]const u8 = undefined;
|
||||||
|
|
||||||
const start = fn export (argc_argv_address: usize) noreturn {
|
const start:: export = fn (argc_argv_address: usize) noreturn {
|
||||||
var argument_address_iterator = argc_argv_address;
|
var argument_address_iterator = argc_argv_address;
|
||||||
const argument_count_ptr: &usize = #cast(argument_address_iterator);
|
const argument_count_ptr: &usize = #cast(argument_address_iterator);
|
||||||
argument_count = argument_count_ptr.@;
|
argument_count = argument_count_ptr.@;
|
||||||
@ -33,6 +33,6 @@ const start = fn export (argc_argv_address: usize) noreturn {
|
|||||||
std.os.exit(exit_code = result);
|
std.os.exit(exit_code = result);
|
||||||
}
|
}
|
||||||
|
|
||||||
const main = fn export (argc: s32, argv: [&:null]?[&:null]u8, env: [&:null]?[&:null]u8) s32 {
|
const main:: export = fn (argc: s32, argv: [&:null]?[&:null]u8, env: [&:null]?[&:null]u8) s32 {
|
||||||
return #import("main").main();
|
return #import("main").main();
|
||||||
}
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user