add char literals

This commit is contained in:
sfja 2024-12-22 02:30:23 +01:00
parent 915b953df3
commit 75b9b53fdd
7 changed files with 61 additions and 3 deletions

View File

@ -40,7 +40,8 @@ export const Ops = {
export type Builtins = typeof Builtins; export type Builtins = typeof Builtins;
export const Builtins = { export const Builtins = {
IntToString: 0x00, Exit: 0x00,
IntToString: 0x01,
StringConcat: 0x10, StringConcat: 0x10,
StringEqual: 0x11, StringEqual: 0x11,
StringCharAt: 0x12, StringCharAt: 0x12,

View File

@ -70,6 +70,32 @@ export class Lexer {
return { ...this.token("int", pos), intValue: 0 }; return { ...this.token("int", pos), intValue: 0 };
} }
if (this.test("'")) {
this.step();
let value: string;
if (this.test("\\")) {
this.step();
if (this.done()) {
this.report("malformed character literal", pos);
return this.token("error", pos);
}
value = {
n: "\n",
t: "\t",
"0": "\0",
}[this.current()] ?? this.current();
} else {
value = this.current();
}
this.step();
if (this.done() || !this.test("'") || value.length === 0) {
this.report("malformed character literal", pos);
return this.token("error", pos);
}
this.step();
return { ...this.token("int", pos), intValue: value.charCodeAt(0) };
}
if (this.test('"')) { if (this.test('"')) {
this.step(); this.step();
let value = ""; let value = "";

View File

@ -37,6 +37,9 @@ syn match Number '0[0-7]\+'
syn match Number '0x[0-9a-fA-F]\+' syn match Number '0x[0-9a-fA-F]\+'
syn match Number '0b[01]\+' syn match Number '0b[01]\+'
syn match Character "'[^\\]'"
syn match Character "'\\.'"
syn region String start=+"+ skip=+\\"+ end=+"+ syn region String start=+"+ skip=+\\"+ end=+"+
syn keyword Todo contained TODO FIXME XXX NOTE syn keyword Todo contained TODO FIXME XXX NOTE

View File

@ -53,6 +53,17 @@
} }
] ]
}, },
"chars": {
"name": "string.quoted.double.slige",
"begin": "'",
"end": "'",
"patterns": [
{
"name": "constant.character.escape.slige",
"match": "\\\\."
}
]
},
"numbers": { "numbers": {
"patterns": [ "patterns": [
{ {

View File

@ -41,7 +41,8 @@ enum class Op : uint32_t {
}; };
enum class Builtin : uint32_t { enum class Builtin : uint32_t {
IntToString = 0x00, Exit = 0x00,
IntToString = 0x01,
StringConcat = 0x10, StringConcat = 0x10,
StringEqual = 0x11, StringEqual = 0x11,
StringCharAt = 0x12, StringCharAt = 0x12,

View File

@ -300,9 +300,15 @@ void VM::run_builtin(Builtin builtin_id)
maybe_builtin_to_string(static_cast<uint32_t>(builtin_id))); maybe_builtin_to_string(static_cast<uint32_t>(builtin_id)));
} }
switch (builtin_id) { switch (builtin_id) {
case Builtin::Exit: {
assert_stack_has(1);
auto status_code = stack_pop().as_int().value;
std::exit(status_code);
break;
}
case Builtin::IntToString: { case Builtin::IntToString: {
assert_stack_has(1); assert_stack_has(1);
auto number = static_cast<int32_t>(stack_pop().as_int().value); auto number = stack_pop().as_int().value;
auto str = std::to_string(number); auto str = std::to_string(number);
stack_push(String(str)); stack_push(String(str));
break; break;

10
tests/char_literal.slg Normal file
View File

@ -0,0 +1,10 @@
fn exit(status_code: int) #[builtin(Exit)] {}
fn main() {
if 'A' != 65 {
exit(1);
}
exit(0);
}