add named arguments

This commit is contained in:
David Gonzalez Martin 2023-11-21 10:44:36 -06:00
parent 956c6ec2d9
commit 4acf1c36f1
5 changed files with 76 additions and 22 deletions

View File

@ -887,12 +887,6 @@ pub const Module = struct {
fn addString(map: *StringKeyMap([]const u8), allocator: Allocator, string: []const u8) !u32 {
const lookup_result = try map.getOrPut(allocator, string, string);
{
const lookup_name = map.getValue(lookup_result.key) orelse unreachable;
assert(equal(u8, lookup_name, string));
}
return lookup_result.key;
}

View File

@ -302,14 +302,66 @@ const Analyzer = struct {
const argument_declarations = function_prototype.arguments.?;
logln(.sema, .call, "Argument declaration count: {}. Argument node list count: {}\n", .{ argument_declarations.len, call_argument_node_list.len });
var argument_array = ArrayList(Value.Index){};
if (argument_declarations.len == call_argument_node_list.len) {
for (argument_declarations, call_argument_node_list) |argument_declaration_index, argument_node_index| {
for (argument_declarations, call_argument_node_list, 0..) |argument_declaration_index, argument_node_index, index| {
const argument_declaration = analyzer.module.declarations.get(argument_declaration_index);
// const argument_declaration_type = analyzer.module.types.get(argument_declaration.type);
// assert(argument_declaration.type.valid);
const argument_node = analyzer.getScopeNode(scope_index, argument_node_index);
const value_node_index = switch (argument_node.id) {
.identifier => blk: {
const identifier = analyzer.tokenIdentifier(scope_index, argument_node.token);
const identifier_hash = try analyzer.processIdentifier(identifier);
if (identifier_hash == argument_declaration.name) {
break :blk argument_node_index;
} else {
const call_site_name = analyzer.module.getName(identifier_hash).?;
const definition_site_name = analyzer.module.getName(argument_declaration.name).?;
const function_name = analyzer.module.getName(analyzer.module.function_name_map.get(function_index).?).?;
std.debug.panic("At function '{s}' call, argument #{} must be named the same way. Call site was name '{s}' while function definition has it named as '{s}'", .{ function_name, index, call_site_name, definition_site_name });
}
},
.named_argument => blk: {
const identifier_node = analyzer.getScopeNode(scope_index, argument_node.left);
if (identifier_node.id != .identifier) {
@panic("expected identifier");
}
const identifier = analyzer.tokenIdentifier(scope_index, identifier_node.token);
const identifier_hash = try analyzer.processIdentifier(identifier);
if (identifier_hash == argument_declaration.name) {
break :blk argument_node.right;
} else {
const call_site_name = analyzer.module.getName(identifier_hash).?;
const definition_site_name = analyzer.module.getName(argument_declaration.name).?;
const function_name = analyzer.module.getName(analyzer.module.function_name_map.get(function_index).?).?;
std.debug.panic("At function '{s}' call, argument #{} must be named the same way. Call site was name '{s}' while function definition has it named as '{s}'", .{ function_name, index, call_site_name, definition_site_name });
}
},
else => |node_id| {
const definition_site_name = analyzer.module.getName(argument_declaration.name).?;
const function_name = analyzer.module.getName(analyzer.module.function_name_map.get(function_index).?).?;
std.debug.panic("Argument #{} of call to function '{s}' of type {s} must be named as '{s}'", .{ index, function_name, @tagName(node_id), definition_site_name });
},
};
const call_argument_allocation = try analyzer.unresolvedAllocate(scope_index, ExpectType{
.type_index = argument_declaration.type,
}, argument_node_index);
}, value_node_index);
// switch (call_argument_allocation.ptr.*) {
// .integer,
// .string_literal,
// => {},
// .declaration_reference => |declaration_reference| {
// if (call_argument_declaration.name != argument_declaration.name) {
// const call_site_name = analyzer.module.getName(call_argument_declaration.name).?;
// const definition_site_name = analyzer.module.getName(argument_declaration.name).?;
// const function_name = analyzer.module.getName(analyzer.module.function_name_map.get(function_index).?).?;
// std.debug.panic("At function '{s}' call, argument #{} must be named the same way. Call site was name '{s}' while function definition has it named as '{s}'", .{ function_name, index, call_site_name, definition_site_name });
// }
// },
// else => |t| @panic(@tagName(t)),
// }
try call_argument_allocation.ptr.typeCheck(analyzer.module, argument_declaration.type);
// const call_argument_type_index = call_argument_allocation.ptr.getType(analyzer.module);
// const call_argument_type = analyzer.module.types.get(call_argument_type_index);

View File

@ -163,6 +163,7 @@ pub const Node = packed struct(u128) {
shift_left = 69,
shift_right = 70,
bool_type = 71,
named_argument = 72,
};
};
@ -1082,20 +1083,27 @@ const Analyzer = struct {
var expression_list = ArrayList(Node.Index){};
while (analyzer.tokens[analyzer.token_i].id != .right_parenthesis) {
const current_token = analyzer.tokens[analyzer.token_i];
logln(.parser, .suffix, "Current token: {s}\n", .{@tagName(current_token.id)});
const parameter = try analyzer.expression();
try expression_list.append(analyzer.allocator, parameter);
const current_token = analyzer.token_i;
var parameter = try analyzer.expression();
const parameter_node = analyzer.nodes.items[parameter.unwrap()];
logln(.parser, .suffix, "Paremeter node: {s}\n", .{@tagName(parameter_node.id)});
const next_token = analyzer.tokens[analyzer.token_i];
logln(.parser, .suffix, "next token: {s}\n", .{@tagName(next_token.id)});
analyzer.token_i += @intFromBool(switch (next_token.id) {
.comma => true,
if (analyzer.tokens[analyzer.token_i].id == .equal) {
analyzer.token_i += 1;
parameter = try analyzer.addNode(.{
.id = .named_argument,
.token = current_token,
.left = parameter,
.right = try analyzer.expression(),
});
}
try expression_list.append(analyzer.allocator, parameter);
switch (analyzer.tokens[analyzer.token_i].id) {
.comma => analyzer.token_i += 1,
.right_parenthesis => {},
.colon, .right_brace, .right_bracket => unreachable,
.right_parenthesis => false,
else => |t| @panic(@tagName(t)),
});
}
}
_ = try analyzer.expectToken(.right_parenthesis);

View File

@ -5,5 +5,5 @@ comptime {
const _start = fn () noreturn {
const result = #import("main").main();
std.os.exit(result);
std.os.exit(exit_code = result);
}

View File

@ -1,6 +1,6 @@
const std = #import("std");
const main = fn() s32 {
std.print("Hello world!\n", 13);
std.print(bytes_ptr = "Hello world!\n", bytes_len = 13);
return 0;
}