Basic string
All checks were successful
All checks were successful
This commit is contained in:
parent
0af6326ac3
commit
13c48c2b94
@ -629,6 +629,7 @@ pub const Value = struct {
|
|||||||
array_expression: ArrayExpression,
|
array_expression: ArrayExpression,
|
||||||
enum_literal: []const u8,
|
enum_literal: []const u8,
|
||||||
field_access: FieldAccess,
|
field_access: FieldAccess,
|
||||||
|
string_literal: []const u8,
|
||||||
},
|
},
|
||||||
type: ?*Type = null,
|
type: ?*Type = null,
|
||||||
llvm: ?*llvm.Value = null,
|
llvm: ?*llvm.Value = null,
|
||||||
@ -1438,6 +1439,12 @@ pub const Module = struct {
|
|||||||
.precedence = .none,
|
.precedence = .none,
|
||||||
};
|
};
|
||||||
count += 1;
|
count += 1;
|
||||||
|
r[@intFromEnum(Token.Id.string_literal)] = .{
|
||||||
|
.before = &rule_before_string_literal,
|
||||||
|
.after = null,
|
||||||
|
.precedence = .none,
|
||||||
|
};
|
||||||
|
count += 1;
|
||||||
r[@intFromEnum(Token.Id.value_keyword)] = .{
|
r[@intFromEnum(Token.Id.value_keyword)] = .{
|
||||||
.before = &rule_before_value_keyword,
|
.before = &rule_before_value_keyword,
|
||||||
.after = null,
|
.after = null,
|
||||||
@ -1885,6 +1892,35 @@ pub const Module = struct {
|
|||||||
module.offset += 1;
|
module.offset += 1;
|
||||||
break :blk .@",";
|
break :blk .@",";
|
||||||
},
|
},
|
||||||
|
'"' => blk: {
|
||||||
|
module.offset += 1;
|
||||||
|
|
||||||
|
const string_literal_start = start_index + 1;
|
||||||
|
while (module.offset < module.content.len) : (module.offset += 1) {
|
||||||
|
if (module.consume_character_if_match('"')) {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
const string_slice = module.content[string_literal_start..][0..(module.offset - 1) - string_literal_start];
|
||||||
|
|
||||||
|
break :blk .{
|
||||||
|
.string_literal = string_slice,
|
||||||
|
};
|
||||||
|
},
|
||||||
|
'\'' => blk: {
|
||||||
|
module.offset += 1;
|
||||||
|
const ch = module.content[module.offset];
|
||||||
|
module.offset += 1;
|
||||||
|
module.expect_character('\'');
|
||||||
|
|
||||||
|
break :blk .{
|
||||||
|
.integer = .{
|
||||||
|
.value = ch,
|
||||||
|
.kind = .decimal,
|
||||||
|
},
|
||||||
|
};
|
||||||
|
},
|
||||||
else => @trap(),
|
else => @trap(),
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -2216,6 +2252,16 @@ pub const Module = struct {
|
|||||||
return value;
|
return value;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn rule_before_string_literal(noalias module: *Module, value_builder: Value.Builder) *Value {
|
||||||
|
const value = module.values.add();
|
||||||
|
value.* = .{
|
||||||
|
.bb = .{
|
||||||
|
.string_literal = value_builder.token.string_literal,
|
||||||
|
},
|
||||||
|
};
|
||||||
|
return value;
|
||||||
|
}
|
||||||
|
|
||||||
fn rule_before_identifier(noalias module: *Module, value_builder: Value.Builder) *Value {
|
fn rule_before_identifier(noalias module: *Module, value_builder: Value.Builder) *Value {
|
||||||
const identifier = value_builder.token.identifier;
|
const identifier = value_builder.token.identifier;
|
||||||
assert(!lib.string.equal(identifier, ""));
|
assert(!lib.string.equal(identifier, ""));
|
||||||
@ -3983,6 +4029,10 @@ pub const Module = struct {
|
|||||||
.right => {
|
.right => {
|
||||||
const element_type = switch (array_expression.array_like.type.?.bb) {
|
const element_type = switch (array_expression.array_like.type.?.bb) {
|
||||||
.pointer => |pointer| pointer.type,
|
.pointer => |pointer| pointer.type,
|
||||||
|
.structure => |structure| switch (structure.is_slice) {
|
||||||
|
true => structure.fields[0].type.bb.pointer.type,
|
||||||
|
false => module.report_error(),
|
||||||
|
},
|
||||||
else => @trap(),
|
else => @trap(),
|
||||||
};
|
};
|
||||||
break :blk switch (value.kind) {
|
break :blk switch (value.kind) {
|
||||||
@ -4017,6 +4067,7 @@ pub const Module = struct {
|
|||||||
else => module.report_error(),
|
else => module.report_error(),
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
.string_literal => module.get_slice_type(.{ .type = module.integer_type(8, false) }),
|
||||||
else => @trap(),
|
else => @trap(),
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -4135,7 +4186,12 @@ pub const Module = struct {
|
|||||||
.value = variable.storage.?.llvm.?,
|
.value = variable.storage.?.llvm.?,
|
||||||
.alignment = variable.storage.?.type.?.bb.pointer.alignment,
|
.alignment = variable.storage.?.type.?.bb.pointer.alignment,
|
||||||
}),
|
}),
|
||||||
.aggregate => @trap(),
|
// TODO: this might be wrong
|
||||||
|
.aggregate => module.create_load(.{
|
||||||
|
.type = value_type,
|
||||||
|
.value = variable.storage.?.llvm.?,
|
||||||
|
.alignment = variable.storage.?.type.?.bb.pointer.alignment,
|
||||||
|
}),
|
||||||
.complex => @trap(),
|
.complex => @trap(),
|
||||||
},
|
},
|
||||||
false => module.report_error(),
|
false => module.report_error(),
|
||||||
@ -4650,6 +4706,26 @@ pub const Module = struct {
|
|||||||
|
|
||||||
break :blk v;
|
break :blk v;
|
||||||
},
|
},
|
||||||
|
.structure => |structure| switch (structure.is_slice) {
|
||||||
|
true => blk: {
|
||||||
|
module.emit_value(function, array_expression.array_like);
|
||||||
|
module.emit_value(function, array_expression.index);
|
||||||
|
const pointer_extract = module.llvm.builder.create_extract_value(array_expression.array_like.llvm.?, 0);
|
||||||
|
const element_type = structure.fields[0].type.bb.pointer.type;
|
||||||
|
const gep = module.llvm.builder.create_gep(.{
|
||||||
|
.type = element_type.llvm.handle.?,
|
||||||
|
.aggregate = pointer_extract,
|
||||||
|
.indices = &.{array_expression.index.llvm.?},
|
||||||
|
});
|
||||||
|
const v = switch (value.kind) {
|
||||||
|
.left => gep,
|
||||||
|
.right => module.create_load(.{ .type = element_type, .value = gep }),
|
||||||
|
};
|
||||||
|
|
||||||
|
break :blk v;
|
||||||
|
},
|
||||||
|
false => module.report_error(),
|
||||||
|
},
|
||||||
else => @trap(),
|
else => @trap(),
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
@ -5035,6 +5111,52 @@ pub const Module = struct {
|
|||||||
},
|
},
|
||||||
false => @trap(),
|
false => @trap(),
|
||||||
},
|
},
|
||||||
|
.string_literal => |string_literal| {
|
||||||
|
const null_terminate = true;
|
||||||
|
const constant_string = module.llvm.context.get_constant_string(string_literal, null_terminate);
|
||||||
|
|
||||||
|
const u8_type = module.integer_type(8, false);
|
||||||
|
const global_variable = module.llvm.module.create_global_variable(.{
|
||||||
|
.linkage = .InternalLinkage,
|
||||||
|
.name = module.arena.join_string(&.{ "conststring" }),
|
||||||
|
.initial_value = constant_string,
|
||||||
|
.type = u8_type.llvm.handle.?.get_array_type(string_literal.len + @intFromBool(null_terminate)).to_type(),
|
||||||
|
});
|
||||||
|
global_variable.set_unnamed_address(.global);
|
||||||
|
|
||||||
|
const slice_type = module.get_slice_type(.{
|
||||||
|
.type = u8_type,
|
||||||
|
});
|
||||||
|
|
||||||
|
switch (value_type.bb) {
|
||||||
|
.structure => |structure| switch (structure.is_slice) {
|
||||||
|
true => switch (slice_type == value_type) {
|
||||||
|
true => {
|
||||||
|
const pointer_to_pointer = module.llvm.builder.create_struct_gep(slice_type.llvm.handle.?.to_struct(), left.llvm.?, 0);
|
||||||
|
const slice_pointer_type = slice_type.bb.structure.fields[0].type;
|
||||||
|
_ = module.create_store(.{
|
||||||
|
.destination_value = pointer_to_pointer,
|
||||||
|
.source_value = global_variable.to_value(),
|
||||||
|
.source_type = slice_pointer_type,
|
||||||
|
.destination_type = slice_pointer_type,
|
||||||
|
});
|
||||||
|
const pointer_to_length = module.llvm.builder.create_struct_gep(slice_type.llvm.handle.?.to_struct(), left.llvm.?, 1);
|
||||||
|
const slice_length_type = slice_type.bb.structure.fields[1].type;
|
||||||
|
const slice_length_value = slice_length_type.llvm.handle.?.to_integer().get_constant(string_literal.len, @intFromBool(false)).to_value();
|
||||||
|
_ = module.create_store(.{
|
||||||
|
.destination_value = pointer_to_length,
|
||||||
|
.source_value = slice_length_value,
|
||||||
|
.source_type = slice_length_type,
|
||||||
|
.destination_type = slice_length_type,
|
||||||
|
});
|
||||||
|
},
|
||||||
|
false => module.report_error(),
|
||||||
|
},
|
||||||
|
false => module.report_error(),
|
||||||
|
},
|
||||||
|
else => @trap(),
|
||||||
|
}
|
||||||
|
},
|
||||||
else => @trap(),
|
else => @trap(),
|
||||||
},
|
},
|
||||||
.complex => @trap(),
|
.complex => @trap(),
|
||||||
@ -5202,6 +5324,7 @@ const Token = union(Id) {
|
|||||||
end_of_statement,
|
end_of_statement,
|
||||||
integer: Integer,
|
integer: Integer,
|
||||||
identifier: []const u8,
|
identifier: []const u8,
|
||||||
|
string_literal: []const u8,
|
||||||
value_keyword: Value.Keyword,
|
value_keyword: Value.Keyword,
|
||||||
value_intrinsic: Value.Intrinsic.Id,
|
value_intrinsic: Value.Intrinsic.Id,
|
||||||
// Assignment operators
|
// Assignment operators
|
||||||
@ -5262,6 +5385,7 @@ const Token = union(Id) {
|
|||||||
end_of_statement,
|
end_of_statement,
|
||||||
integer,
|
integer,
|
||||||
identifier,
|
identifier,
|
||||||
|
string_literal,
|
||||||
value_keyword,
|
value_keyword,
|
||||||
value_intrinsic,
|
value_intrinsic,
|
||||||
// Assignment operators
|
// Assignment operators
|
||||||
|
@ -209,4 +209,5 @@ const names = &[_][]const u8{
|
|||||||
"assignment_operators",
|
"assignment_operators",
|
||||||
"basic_enum",
|
"basic_enum",
|
||||||
"basic_slice",
|
"basic_slice",
|
||||||
|
"basic_string",
|
||||||
};
|
};
|
||||||
|
Loading…
x
Reference in New Issue
Block a user