add named arguments
This commit is contained in:
parent
956c6ec2d9
commit
4acf1c36f1
@ -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;
|
||||
}
|
||||
|
||||
|
@ -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);
|
||||
|
@ -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);
|
||||
|
@ -5,5 +5,5 @@ comptime {
|
||||
|
||||
const _start = fn () noreturn {
|
||||
const result = #import("main").main();
|
||||
std.os.exit(result);
|
||||
std.os.exit(exit_code = result);
|
||||
}
|
||||
|
@ -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;
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user