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 {
|
fn addString(map: *StringKeyMap([]const u8), allocator: Allocator, string: []const u8) !u32 {
|
||||||
const lookup_result = try map.getOrPut(allocator, string, string);
|
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;
|
return lookup_result.key;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -302,14 +302,66 @@ const Analyzer = struct {
|
|||||||
const argument_declarations = function_prototype.arguments.?;
|
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 });
|
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){};
|
var argument_array = ArrayList(Value.Index){};
|
||||||
|
|
||||||
if (argument_declarations.len == call_argument_node_list.len) {
|
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 = analyzer.module.declarations.get(argument_declaration_index);
|
||||||
// const argument_declaration_type = analyzer.module.types.get(argument_declaration.type);
|
const argument_node = analyzer.getScopeNode(scope_index, argument_node_index);
|
||||||
// assert(argument_declaration.type.valid);
|
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{
|
const call_argument_allocation = try analyzer.unresolvedAllocate(scope_index, ExpectType{
|
||||||
.type_index = argument_declaration.type,
|
.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);
|
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_index = call_argument_allocation.ptr.getType(analyzer.module);
|
||||||
// const call_argument_type = analyzer.module.types.get(call_argument_type_index);
|
// 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_left = 69,
|
||||||
shift_right = 70,
|
shift_right = 70,
|
||||||
bool_type = 71,
|
bool_type = 71,
|
||||||
|
named_argument = 72,
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -1082,21 +1083,28 @@ const Analyzer = struct {
|
|||||||
|
|
||||||
var expression_list = ArrayList(Node.Index){};
|
var expression_list = ArrayList(Node.Index){};
|
||||||
while (analyzer.tokens[analyzer.token_i].id != .right_parenthesis) {
|
while (analyzer.tokens[analyzer.token_i].id != .right_parenthesis) {
|
||||||
const current_token = analyzer.tokens[analyzer.token_i];
|
const current_token = analyzer.token_i;
|
||||||
logln(.parser, .suffix, "Current token: {s}\n", .{@tagName(current_token.id)});
|
var parameter = try analyzer.expression();
|
||||||
const parameter = try analyzer.expression();
|
|
||||||
try expression_list.append(analyzer.allocator, parameter);
|
|
||||||
const parameter_node = analyzer.nodes.items[parameter.unwrap()];
|
const parameter_node = analyzer.nodes.items[parameter.unwrap()];
|
||||||
logln(.parser, .suffix, "Paremeter node: {s}\n", .{@tagName(parameter_node.id)});
|
logln(.parser, .suffix, "Paremeter node: {s}\n", .{@tagName(parameter_node.id)});
|
||||||
const next_token = analyzer.tokens[analyzer.token_i];
|
if (analyzer.tokens[analyzer.token_i].id == .equal) {
|
||||||
logln(.parser, .suffix, "next token: {s}\n", .{@tagName(next_token.id)});
|
analyzer.token_i += 1;
|
||||||
analyzer.token_i += @intFromBool(switch (next_token.id) {
|
|
||||||
.comma => true,
|
parameter = try analyzer.addNode(.{
|
||||||
.colon, .right_brace, .right_bracket => unreachable,
|
.id = .named_argument,
|
||||||
.right_parenthesis => false,
|
.token = current_token,
|
||||||
else => |t| @panic(@tagName(t)),
|
.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,
|
||||||
|
else => |t| @panic(@tagName(t)),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
_ = try analyzer.expectToken(.right_parenthesis);
|
_ = try analyzer.expectToken(.right_parenthesis);
|
||||||
// const is_comma = analyzer.tokens[analyzer.token_i].id == .comma;
|
// const is_comma = analyzer.tokens[analyzer.token_i].id == .comma;
|
||||||
|
@ -5,5 +5,5 @@ comptime {
|
|||||||
|
|
||||||
const _start = fn () noreturn {
|
const _start = fn () noreturn {
|
||||||
const result = #import("main").main();
|
const result = #import("main").main();
|
||||||
std.os.exit(result);
|
std.os.exit(exit_code = result);
|
||||||
}
|
}
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
const std = #import("std");
|
const std = #import("std");
|
||||||
|
|
||||||
const main = fn() s32 {
|
const main = fn() s32 {
|
||||||
std.print("Hello world!\n", 13);
|
std.print(bytes_ptr = "Hello world!\n", bytes_len = 13);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user