Constant add
This commit is contained in:
parent
c4d25ca393
commit
892360a084
@ -144,53 +144,71 @@ const Converter = struct {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn parse_integer(noalias converter: *Converter, expected_type: *llvm.Type) *llvm.Value {
|
fn parse_decimal(noalias converter: *Converter) u64 {
|
||||||
|
var value: u64 = 0;
|
||||||
|
while (true) {
|
||||||
|
const ch = converter.content[converter.offset];
|
||||||
|
if (!is_decimal_ch(ch)) {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
converter.offset += 1;
|
||||||
|
value = lib.parse.accumulate_decimal(value, ch);
|
||||||
|
}
|
||||||
|
|
||||||
|
return value;
|
||||||
|
}
|
||||||
|
|
||||||
|
fn parse_integer(noalias converter: *Converter, expected_type: *llvm.Type, signed: bool) *llvm.Value {
|
||||||
const start = converter.offset;
|
const start = converter.offset;
|
||||||
const integer_start_ch = converter.content[start];
|
const integer_start_ch = converter.content[start];
|
||||||
assert(!is_space(integer_start_ch));
|
assert(!is_space(integer_start_ch));
|
||||||
assert(is_decimal_ch(integer_start_ch));
|
assert(is_decimal_ch(integer_start_ch));
|
||||||
const integer_type = expected_type.to_integer();
|
const integer_type = expected_type.to_integer();
|
||||||
|
|
||||||
const sign_extend = false;
|
const sign_extend = signed;
|
||||||
var value: u64 = 0;
|
|
||||||
|
|
||||||
switch (integer_start_ch) {
|
|
||||||
'0' => {
|
|
||||||
converter.offset += 1;
|
|
||||||
|
|
||||||
switch (converter.content[converter.offset]) {
|
|
||||||
'x' => {
|
|
||||||
// TODO: parse hexadecimal
|
|
||||||
converter.report_error();
|
|
||||||
},
|
|
||||||
'o' => {
|
|
||||||
// TODO: parse octal
|
|
||||||
converter.report_error();
|
|
||||||
},
|
|
||||||
'b' => {
|
|
||||||
// TODO: parse binary
|
|
||||||
converter.report_error();
|
|
||||||
},
|
|
||||||
'0'...'9' => {
|
|
||||||
converter.report_error();
|
|
||||||
},
|
|
||||||
// Zero literal
|
|
||||||
else => {},
|
|
||||||
}
|
|
||||||
},
|
|
||||||
'1'...'9' => {
|
|
||||||
while (true) {
|
|
||||||
const ch = converter.content[converter.offset];
|
|
||||||
if (!is_decimal_ch(ch)) {
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
const value: u64 = switch (signed) {
|
||||||
|
true => switch (integer_start_ch) {
|
||||||
|
'0' => blk: {
|
||||||
converter.offset += 1;
|
converter.offset += 1;
|
||||||
value = lib.parse.accumulate_decimal(value, ch);
|
|
||||||
}
|
switch (converter.content[converter.offset]) {
|
||||||
|
'x', 'o', 'b', '0'...'9' => converter.report_error(),
|
||||||
|
else => break :blk 0,
|
||||||
|
}
|
||||||
|
},
|
||||||
|
'1'...'9' => @bitCast(-@as(i64, @intCast(converter.parse_decimal()))),
|
||||||
|
else => unreachable,
|
||||||
},
|
},
|
||||||
else => unreachable,
|
false => switch (integer_start_ch) {
|
||||||
}
|
'0' => blk: {
|
||||||
|
converter.offset += 1;
|
||||||
|
|
||||||
|
switch (converter.content[converter.offset]) {
|
||||||
|
'x' => {
|
||||||
|
// TODO: parse hexadecimal
|
||||||
|
converter.report_error();
|
||||||
|
},
|
||||||
|
'o' => {
|
||||||
|
// TODO: parse octal
|
||||||
|
converter.report_error();
|
||||||
|
},
|
||||||
|
'b' => {
|
||||||
|
// TODO: parse binary
|
||||||
|
converter.report_error();
|
||||||
|
},
|
||||||
|
'0'...'9' => {
|
||||||
|
converter.report_error();
|
||||||
|
},
|
||||||
|
// Zero literal
|
||||||
|
else => break :blk 0,
|
||||||
|
}
|
||||||
|
},
|
||||||
|
'1'...'9' => converter.parse_decimal(),
|
||||||
|
else => unreachable,
|
||||||
|
},
|
||||||
|
};
|
||||||
|
|
||||||
const integer_value = integer_type.get_constant(value, @intFromBool(sign_extend));
|
const integer_value = integer_type.get_constant(value, @intFromBool(sign_extend));
|
||||||
return integer_value.to_value();
|
return integer_value.to_value();
|
||||||
@ -251,6 +269,7 @@ const Converter = struct {
|
|||||||
const ExpressionState = enum {
|
const ExpressionState = enum {
|
||||||
none,
|
none,
|
||||||
sub,
|
sub,
|
||||||
|
add,
|
||||||
};
|
};
|
||||||
|
|
||||||
fn parse_value(noalias converter: *Converter, noalias thread: *llvm.Thread, expected_type: *llvm.Type) *llvm.Value {
|
fn parse_value(noalias converter: *Converter, noalias thread: *llvm.Thread, expected_type: *llvm.Type) *llvm.Value {
|
||||||
@ -267,14 +286,14 @@ const Converter = struct {
|
|||||||
|
|
||||||
converter.skip_space();
|
converter.skip_space();
|
||||||
|
|
||||||
switch (value_state) {
|
const left = previous_value;
|
||||||
.none => previous_value = current_value,
|
const right = current_value;
|
||||||
.sub => {
|
|
||||||
const left = previous_value;
|
previous_value = switch (value_state) {
|
||||||
const right = current_value;
|
.none => current_value,
|
||||||
previous_value = thread.builder.create_sub(left, right);
|
.sub => thread.builder.create_sub(left, right),
|
||||||
},
|
.add => thread.builder.create_add(left, right),
|
||||||
}
|
};
|
||||||
|
|
||||||
const ch = converter.content[converter.offset];
|
const ch = converter.content[converter.offset];
|
||||||
value_state = switch (ch) {
|
value_state = switch (ch) {
|
||||||
@ -283,6 +302,10 @@ const Converter = struct {
|
|||||||
converter.offset += 1;
|
converter.offset += 1;
|
||||||
break :blk .sub;
|
break :blk .sub;
|
||||||
},
|
},
|
||||||
|
'+' => blk: {
|
||||||
|
converter.offset += 1;
|
||||||
|
break :blk .add;
|
||||||
|
},
|
||||||
else => os.abort(),
|
else => os.abort(),
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -292,19 +315,51 @@ const Converter = struct {
|
|||||||
return value;
|
return value;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const Prefix = enum {
|
||||||
|
none,
|
||||||
|
negative,
|
||||||
|
};
|
||||||
|
|
||||||
fn parse_single_value(noalias converter: *Converter, expected_type: *llvm.Type) *llvm.Value {
|
fn parse_single_value(noalias converter: *Converter, expected_type: *llvm.Type) *llvm.Value {
|
||||||
converter.skip_space();
|
converter.skip_space();
|
||||||
|
|
||||||
const start = converter.offset;
|
const prefix_offset = converter.offset;
|
||||||
const value_start_ch = converter.content[start];
|
const prefix_ch = converter.content[prefix_offset];
|
||||||
if (is_identifier_start_ch(value_start_ch)) {
|
var is_signed = false;
|
||||||
converter.report_error();
|
const prefix: Prefix = switch (prefix_ch) {
|
||||||
} else if (is_decimal_ch(value_start_ch)) {
|
'a'...'z', 'A'...'Z', '_', '0'...'9' => .none,
|
||||||
const value = converter.parse_integer(expected_type);
|
'-' => blk: {
|
||||||
return value;
|
converter.offset += 1;
|
||||||
} else {
|
|
||||||
converter.report_error();
|
// TODO: should we skip space here?
|
||||||
}
|
converter.skip_space();
|
||||||
|
is_signed = true;
|
||||||
|
break :blk .negative;
|
||||||
|
},
|
||||||
|
else => os.abort(),
|
||||||
|
};
|
||||||
|
_ = prefix;
|
||||||
|
|
||||||
|
const value_offset = converter.offset;
|
||||||
|
const value_start_ch = converter.content[value_offset];
|
||||||
|
const value = switch (value_start_ch) {
|
||||||
|
'a'...'z', 'A'...'Z', '_' => os.abort(),
|
||||||
|
'0'...'9' => converter.parse_integer(expected_type, is_signed),
|
||||||
|
else => os.abort(),
|
||||||
|
};
|
||||||
|
|
||||||
|
return value;
|
||||||
|
// if (is_identifier_start_ch(value_start_ch)) {
|
||||||
|
// converter.report_error();
|
||||||
|
// } else if (is_decimal_ch(value_start_ch)) {
|
||||||
|
// const value = converter.parse_integer(expected_type);
|
||||||
|
// return value;
|
||||||
|
// } else if ({
|
||||||
|
// switch (value_start_ch) {
|
||||||
|
//
|
||||||
|
// }
|
||||||
|
// converter.report_error();
|
||||||
|
// }
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -631,6 +686,10 @@ test "minimal" {
|
|||||||
try invoke("minimal");
|
try invoke("minimal");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
test "constant add" {
|
||||||
|
try invoke("constant_add");
|
||||||
|
}
|
||||||
|
|
||||||
test "constant sub" {
|
test "constant sub" {
|
||||||
try invoke("constant_sub");
|
try invoke("constant_sub");
|
||||||
}
|
}
|
||||||
|
5
tests/constant_add.bbb
Normal file
5
tests/constant_add.bbb
Normal file
@ -0,0 +1,5 @@
|
|||||||
|
[export] main = fn [cc(c)] () s32
|
||||||
|
{
|
||||||
|
return -1 + 1;
|
||||||
|
}
|
||||||
|
|
Loading…
x
Reference in New Issue
Block a user