mirror of
https://git.sfja.dk/Mikkel/slige.git
synced 2025-01-18 18:36:31 +00:00
everything
This commit is contained in:
parent
7c83c7296d
commit
219785e465
@ -38,11 +38,13 @@ export const Ops = {
|
|||||||
|
|
||||||
export type Builtins = typeof Builtins;
|
export type Builtins = typeof Builtins;
|
||||||
export const Builtins = {
|
export const Builtins = {
|
||||||
|
IntToString: 0x00,
|
||||||
StringConcat: 0x10,
|
StringConcat: 0x10,
|
||||||
StringEqual: 0x11,
|
StringEqual: 0x11,
|
||||||
StringCharAt: 0x12,
|
StringCharAt: 0x12,
|
||||||
StringLength: 0x13,
|
StringLength: 0x13,
|
||||||
StringPushChar: 0x14,
|
StringPushChar: 0x14,
|
||||||
|
StringToInt: 0x15,
|
||||||
ArrayNew: 0x20,
|
ArrayNew: 0x20,
|
||||||
ArraySet: 0x21,
|
ArraySet: 0x21,
|
||||||
ArrayPush: 0x22,
|
ArrayPush: 0x22,
|
||||||
|
@ -198,8 +198,8 @@ export class Checker {
|
|||||||
}
|
}
|
||||||
case "index": {
|
case "index": {
|
||||||
const subject = this.checkExpr(stmt.kind.subject.kind.subject);
|
const subject = this.checkExpr(stmt.kind.subject.kind.subject);
|
||||||
if (subject.type !== "array") {
|
if (subject.type !== "array" && subject.type !== "string") {
|
||||||
this.report("cannot index on non-array", pos);
|
this.report(`cannot index on non-array, got: ${subject.type}`, pos);
|
||||||
return { type: "error" };
|
return { type: "error" };
|
||||||
}
|
}
|
||||||
const indexValue = this.checkExpr(stmt.kind.subject.kind.value);
|
const indexValue = this.checkExpr(stmt.kind.subject.kind.value);
|
||||||
@ -207,7 +207,7 @@ export class Checker {
|
|||||||
this.report("cannot index on array with non-int", pos);
|
this.report("cannot index on array with non-int", pos);
|
||||||
return { type: "error" };
|
return { type: "error" };
|
||||||
}
|
}
|
||||||
if (!vtypesEqual(subject.inner, value)) {
|
if (subject.type == "array" && !vtypesEqual(subject.inner, value)) {
|
||||||
this.report(
|
this.report(
|
||||||
`cannot assign incompatible type to array ` +
|
`cannot assign incompatible type to array ` +
|
||||||
`'${vtypeToString(subject)}'` +
|
`'${vtypeToString(subject)}'` +
|
||||||
@ -345,8 +345,8 @@ export class Checker {
|
|||||||
}
|
}
|
||||||
const pos = expr.pos;
|
const pos = expr.pos;
|
||||||
const subject = this.checkExpr(expr.kind.subject);
|
const subject = this.checkExpr(expr.kind.subject);
|
||||||
if (subject.type !== "array") {
|
if (subject.type !== "array" && subject.type !== "string") {
|
||||||
this.report("cannot index on non-array", pos);
|
this.report(`cannot index on non-array, got: ${subject.type}`, pos);
|
||||||
return { type: "error" };
|
return { type: "error" };
|
||||||
}
|
}
|
||||||
const value = this.checkExpr(expr.kind.value);
|
const value = this.checkExpr(expr.kind.value);
|
||||||
@ -354,7 +354,10 @@ export class Checker {
|
|||||||
this.report("cannot index on array with non-int", pos);
|
this.report("cannot index on array with non-int", pos);
|
||||||
return { type: "error" };
|
return { type: "error" };
|
||||||
}
|
}
|
||||||
return subject.inner;
|
if (subject.type === "array") {
|
||||||
|
return subject.inner;
|
||||||
|
}
|
||||||
|
return { type: "int" }
|
||||||
}
|
}
|
||||||
|
|
||||||
public checkCallExpr(expr: Expr): VType {
|
public checkCallExpr(expr: Expr): VType {
|
||||||
|
@ -224,7 +224,7 @@ export class Lowerer {
|
|||||||
case "field":
|
case "field":
|
||||||
break;
|
break;
|
||||||
case "index":
|
case "index":
|
||||||
break;
|
return this.lowerIndexExpr(expr);
|
||||||
case "call":
|
case "call":
|
||||||
return this.lowerCallExpr(expr);
|
return this.lowerCallExpr(expr);
|
||||||
case "unary":
|
case "unary":
|
||||||
@ -241,6 +241,24 @@ export class Lowerer {
|
|||||||
throw new Error(`unhandled expr '${expr.kind.type}'`);
|
throw new Error(`unhandled expr '${expr.kind.type}'`);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private lowerIndexExpr(expr: Expr) {
|
||||||
|
if (expr.kind.type !== "index") {
|
||||||
|
throw new Error();
|
||||||
|
}
|
||||||
|
this.lowerExpr(expr.kind.subject)
|
||||||
|
this.lowerExpr(expr.kind.value)
|
||||||
|
|
||||||
|
if (expr.kind.subject.vtype?.type == "array") {
|
||||||
|
this.program.add(Ops.Builtin, Builtins.ArrayAt);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if (expr.kind.subject.vtype?.type == "string") {
|
||||||
|
this.program.add(Ops.Builtin, Builtins.StringCharAt);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
throw new Error(`unhandled index subject type '${expr.kind.subject}'`);
|
||||||
|
}
|
||||||
|
|
||||||
private lowerSymExpr(expr: Expr) {
|
private lowerSymExpr(expr: Expr) {
|
||||||
if (expr.kind.type !== "sym") {
|
if (expr.kind.type !== "sym") {
|
||||||
throw new Error();
|
throw new Error();
|
||||||
|
@ -1,4 +1,5 @@
|
|||||||
{
|
{
|
||||||
|
<<<<<<< HEAD
|
||||||
"$schema": "https://raw.githubusercontent.com/martinring/tmlanguage/master/tmlanguage.json",
|
"$schema": "https://raw.githubusercontent.com/martinring/tmlanguage/master/tmlanguage.json",
|
||||||
"name": "Slige",
|
"name": "Slige",
|
||||||
"patterns": [
|
"patterns": [
|
||||||
@ -12,6 +13,83 @@
|
|||||||
],
|
],
|
||||||
"repository": {
|
"repository": {
|
||||||
"keywords": {
|
"keywords": {
|
||||||
|
=======
|
||||||
|
"$schema": "https://raw.githubusercontent.com/martinring/tmlanguage/master/tmlanguage.json",
|
||||||
|
"name": "Slige",
|
||||||
|
"patterns": [
|
||||||
|
{ "include": "#comments" },
|
||||||
|
{ "include": "#keywords" },
|
||||||
|
{ "include": "#strings" },
|
||||||
|
{ "include": "#numbers" },
|
||||||
|
{ "include": "#operators" },
|
||||||
|
{ "include": "#punctuation" },
|
||||||
|
{ "include": "#functions" },
|
||||||
|
{ "include": "#idents" }
|
||||||
|
],
|
||||||
|
"repository": {
|
||||||
|
"comments": {
|
||||||
|
"patterns": [
|
||||||
|
{
|
||||||
|
"name": "comment.line.slige",
|
||||||
|
"begin": "//",
|
||||||
|
"end": "\\n"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "comment.block.slige",
|
||||||
|
"begin": "/\\*",
|
||||||
|
"end": "\\*/"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"keywords": {
|
||||||
|
"patterns": [
|
||||||
|
{
|
||||||
|
"name": "keyword.control.slige",
|
||||||
|
"match": "\\b(break|return|let|fn|loop|if|else|struct|import|or|and|not)\\b"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "constant.language.slige",
|
||||||
|
"match": "\\b(null|false|true)\\b"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "storage.type.slige",
|
||||||
|
"match": "\\b(int|string|bool)\\b"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"strings": {
|
||||||
|
"name": "string.quoted.double.slige",
|
||||||
|
"begin": "\"",
|
||||||
|
"end": "\"",
|
||||||
|
"patterns": [
|
||||||
|
{
|
||||||
|
"name": "constant.character.escape.slige",
|
||||||
|
"match": "\\\\."
|
||||||
|
}
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"numbers": {
|
||||||
|
"patterns": [
|
||||||
|
{
|
||||||
|
"name": "constant.numeric.slige",
|
||||||
|
"match": "\\b0\\b"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "constant.numeric.slige",
|
||||||
|
"match": "\\b[1-9][0-9]*(\\.[0-9]+)?\\b"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "constant.numeric.slige",
|
||||||
|
"match": "\\b0x[0-9a-fA-F]+?\\b"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "constant.numeric.slige",
|
||||||
|
"match": "\\b0b[01]+?\\b"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"operators": {
|
||||||
|
>>>>>>> 53a965f (everything)
|
||||||
"patterns": [
|
"patterns": [
|
||||||
{
|
{
|
||||||
"name": "keyword.control.slige",
|
"name": "keyword.control.slige",
|
||||||
|
190
examples/advent_of_code/day2.slg
Normal file
190
examples/advent_of_code/day2.slg
Normal file
@ -0,0 +1,190 @@
|
|||||||
|
|
||||||
|
|
||||||
|
fn print(msg: string) #[builtin(Print)] {}
|
||||||
|
fn println(msg: string) { print(msg + "\n") }
|
||||||
|
|
||||||
|
fn int_to_string(number: int) -> string #[builtin(IntToString)] {}
|
||||||
|
|
||||||
|
fn string_push_char(str: string, value: int) -> string #[builtin(StringPushChar)] {}
|
||||||
|
fn string_length(str: string) -> int #[builtin(StringLength)] {}
|
||||||
|
fn string_to_int(str: string) -> int #[builtin(StringToInt)] {}
|
||||||
|
|
||||||
|
fn array_new_string() -> [string] #[builtin(ArrayNew)] {}
|
||||||
|
fn array_new_int() -> [int] #[builtin(ArrayNew)] {}
|
||||||
|
fn array_push_string(array: [string], value: string) #[builtin(ArrayPush)] {}
|
||||||
|
fn array_push_int(array: [int], value: int) #[builtin(ArrayPush)] {}
|
||||||
|
fn array_length_string(array: [string]) -> int #[builtin(ArrayLength)] {}
|
||||||
|
fn array_length_int(array: [int]) -> int #[builtin(ArrayLength)] {}
|
||||||
|
|
||||||
|
fn char(ch: string) -> int {
|
||||||
|
ch[0]
|
||||||
|
}
|
||||||
|
|
||||||
|
fn abs(number: int) -> int {
|
||||||
|
let result = number;
|
||||||
|
if number < 0 {
|
||||||
|
result = number - (number * 2);
|
||||||
|
}
|
||||||
|
result
|
||||||
|
}
|
||||||
|
|
||||||
|
fn split(str: string, seperator: int) -> [string] {
|
||||||
|
let result: [string] = array_new_string();
|
||||||
|
|
||||||
|
let i = 0;
|
||||||
|
let current_str = "";
|
||||||
|
loop {
|
||||||
|
if i >= string_length(str) {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
let char = str[i];
|
||||||
|
if char == seperator {
|
||||||
|
array_push_string(result, current_str);
|
||||||
|
current_str = "";
|
||||||
|
} else {
|
||||||
|
current_str = string_push_char(current_str, char);
|
||||||
|
}
|
||||||
|
i = i + 1;
|
||||||
|
}
|
||||||
|
array_push_string(result, current_str);
|
||||||
|
result
|
||||||
|
}
|
||||||
|
|
||||||
|
fn slice(str: string, from: int, to: int) -> string {
|
||||||
|
let result = "";
|
||||||
|
let i = from;
|
||||||
|
loop {
|
||||||
|
if i >= string_length(str) {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
if i >= to {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
result = string_push_char(result, str[i]);
|
||||||
|
i = i + 1;
|
||||||
|
}
|
||||||
|
result
|
||||||
|
}
|
||||||
|
|
||||||
|
// fn triangle_sort(array: [int]) -> [int] {
|
||||||
|
// let result: [int] = array_new_int();
|
||||||
|
// let i = 0;
|
||||||
|
// loop {
|
||||||
|
// if i >= array_length_int(array) {
|
||||||
|
// break;
|
||||||
|
// }
|
||||||
|
// let j = i;
|
||||||
|
// let current_lowest_int = array[0];
|
||||||
|
// loop {
|
||||||
|
// if j >= array_length_int(array) {
|
||||||
|
// break;
|
||||||
|
// }
|
||||||
|
// let current_int = array[j];
|
||||||
|
// if current_int < current_lowest_int {
|
||||||
|
// current_lowest_int = current_int;
|
||||||
|
// }
|
||||||
|
// j = j + 1;
|
||||||
|
// }
|
||||||
|
// array_push_int(result, current_lowest_int);
|
||||||
|
// i = i + 1;
|
||||||
|
// }
|
||||||
|
// result
|
||||||
|
// }
|
||||||
|
|
||||||
|
fn array_clone(array: [int]) -> [int] {
|
||||||
|
let len = array_length_int(array);
|
||||||
|
let result = array_new_int();
|
||||||
|
let i = 0;
|
||||||
|
loop {
|
||||||
|
if i >= len { break; }
|
||||||
|
result[i] = array[i];
|
||||||
|
i = 1 + 1;
|
||||||
|
}
|
||||||
|
result
|
||||||
|
}
|
||||||
|
|
||||||
|
fn array_sort_mut(array: [int]) {
|
||||||
|
let len = array_length_int(array);
|
||||||
|
let i = 0;
|
||||||
|
loop {
|
||||||
|
if i >= len { break; }
|
||||||
|
let j = i + 1;
|
||||||
|
loop {
|
||||||
|
if j >= len { break; }
|
||||||
|
if array[j] < array[i] {
|
||||||
|
let tmp = array[j];
|
||||||
|
array[j] = array[i];
|
||||||
|
array[i] = tmp;
|
||||||
|
}
|
||||||
|
j = j + 1;
|
||||||
|
}
|
||||||
|
i = 1 + 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fn array_to_sorted(array: [int]) -> [int] {
|
||||||
|
let cloned = array_clone(array);
|
||||||
|
array_sort_mut(array);
|
||||||
|
cloned
|
||||||
|
}
|
||||||
|
|
||||||
|
fn location_ids() -> string {
|
||||||
|
"49744 57964
|
||||||
|
20738 85861
|
||||||
|
20319 65072
|
||||||
|
79568 74248
|
||||||
|
78194 83454
|
||||||
|
48701 94102
|
||||||
|
69552 26808
|
||||||
|
62781 67392
|
||||||
|
85323 47428
|
||||||
|
99344 72568
|
||||||
|
27523 97243
|
||||||
|
48039 36600
|
||||||
|
91532 31571
|
||||||
|
21306 31571
|
||||||
|
52409 10805
|
||||||
|
33901 31571
|
||||||
|
80772 38756
|
||||||
|
13849 54584
|
||||||
|
72294 28326
|
||||||
|
86065 65553
|
||||||
|
93987 72533
|
||||||
|
81640 39741
|
||||||
|
25701 89912
|
||||||
|
98611 57082
|
||||||
|
80949 94974
|
||||||
|
84717 61876
|
||||||
|
31599 57082
|
||||||
|
87119 65871
|
||||||
|
56659 22897"
|
||||||
|
}
|
||||||
|
|
||||||
|
fn main() {
|
||||||
|
let location_ids = split(location_ids(), char("\n"));
|
||||||
|
let i = 0;
|
||||||
|
let left_ids: [int] = array_new_int();
|
||||||
|
let right_ids: [int] = array_new_int();
|
||||||
|
loop {
|
||||||
|
if i >= array_length_string(location_ids) {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
array_push_int(left_ids, string_to_int(slice(location_ids[i], 0, 5)));
|
||||||
|
array_push_int(right_ids, string_to_int(slice(location_ids[i], 8, 13)));
|
||||||
|
i = i + 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
let sorted_left_ids: [int] = array_to_sorted(left_ids);
|
||||||
|
// let sorted_right_ids: [int] = array_to_sorted(right_ids);
|
||||||
|
// i = 0;
|
||||||
|
// let sum = 0;
|
||||||
|
// loop {
|
||||||
|
// if i >= array_length_int(left_ids) {
|
||||||
|
// break;
|
||||||
|
// }
|
||||||
|
// let difference = abs(sorted_left_ids[i] - sorted_right_ids[i]);
|
||||||
|
// let sum = sum + difference;
|
||||||
|
// i = i + 1;
|
||||||
|
// }
|
||||||
|
// println(int_to_string(sum))
|
||||||
|
}
|
38
examples/example_3.slg
Normal file
38
examples/example_3.slg
Normal file
@ -0,0 +1,38 @@
|
|||||||
|
fn print(msg: string) #[builtin(Print)] {}
|
||||||
|
fn println(msg: string) { print(msg + "\n") }
|
||||||
|
|
||||||
|
fn array_length_int(array: [int]) -> int #[builtin(ArrayLength)] {}
|
||||||
|
fn array_new_int() -> [int] #[builtin(ArrayNew)] {}
|
||||||
|
fn array_push_int(array: [int], value: int) #[builtin(ArrayPush)] {}
|
||||||
|
|
||||||
|
fn int_to_string(number: int) -> string #[builtin(IntToString)] {}
|
||||||
|
|
||||||
|
fn add(a: int, b: int) -> int {
|
||||||
|
a + b
|
||||||
|
}
|
||||||
|
|
||||||
|
fn main() -> int {
|
||||||
|
let result = 0;
|
||||||
|
let array = array_new_int();
|
||||||
|
|
||||||
|
let i = 0;
|
||||||
|
loop {
|
||||||
|
if i >= 10 {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
array_push_int(array, i);
|
||||||
|
i = i + 1;
|
||||||
|
}
|
||||||
|
i = 0;
|
||||||
|
loop {
|
||||||
|
if i >= array_length_int(array) {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
result = add(array[i], array[i]);
|
||||||
|
println(int_to_string(result));
|
||||||
|
i = i + 1;
|
||||||
|
}
|
||||||
|
result
|
||||||
|
}
|
||||||
|
|
@ -1,10 +1,19 @@
|
|||||||
|
|
||||||
|
# CXX_FLAGS = \
|
||||||
|
# -std=c++23 \
|
||||||
|
# -Og \
|
||||||
|
# -fsanitize=address,undefined \
|
||||||
|
# -pedantic -pedantic-errors \
|
||||||
|
# -Wall -Wextra -Wpedantic -Wconversion -Werror \
|
||||||
|
|
||||||
|
|
||||||
CXX_FLAGS = \
|
CXX_FLAGS = \
|
||||||
-std=c++23 \
|
-std=c++23 \
|
||||||
-Og \
|
|
||||||
-fsanitize=address,undefined \
|
-fsanitize=address,undefined \
|
||||||
|
-Og \
|
||||||
-pedantic -pedantic-errors \
|
-pedantic -pedantic-errors \
|
||||||
-Wall -Wextra -Wpedantic -Wconversion \
|
-Wall -Wextra -Wpedantic -Wconversion -Werror \
|
||||||
|
|
||||||
|
|
||||||
OUT=build/sliger
|
OUT=build/sliger
|
||||||
|
|
||||||
|
@ -38,7 +38,7 @@ private:
|
|||||||
std::vector<uint32_t> instructions;
|
std::vector<uint32_t> instructions;
|
||||||
};
|
};
|
||||||
|
|
||||||
static auto action_from_json(
|
static inline auto action_from_json(
|
||||||
std::unique_ptr<json::Value> value) -> std::unique_ptr<Action>
|
std::unique_ptr<json::Value> value) -> std::unique_ptr<Action>
|
||||||
{
|
{
|
||||||
auto& obj = value->as<sliger::json::Object>();
|
auto& obj = value->as<sliger::json::Object>();
|
||||||
|
@ -13,6 +13,13 @@ namespace sliger::heap {
|
|||||||
|
|
||||||
struct Array {
|
struct Array {
|
||||||
std::vector<Value> values;
|
std::vector<Value> values;
|
||||||
|
inline auto at(int32_t index)& -> Value& {
|
||||||
|
if (index >= static_cast<int32_t>(this->values.size()) || index < 0) {
|
||||||
|
std::cout << std::format("index not in range, expected to be in range (0..{}), got: {}", this->values.size(), index);
|
||||||
|
exit(1);
|
||||||
|
}
|
||||||
|
return values.at(index);
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
struct Struct {
|
struct Struct {
|
||||||
|
@ -39,11 +39,13 @@ enum class Op : uint32_t {
|
|||||||
};
|
};
|
||||||
|
|
||||||
enum class Builtin : uint32_t {
|
enum class Builtin : uint32_t {
|
||||||
|
IntToString = 0x00,
|
||||||
StringConcat = 0x10,
|
StringConcat = 0x10,
|
||||||
StringEqual = 0x11,
|
StringEqual = 0x11,
|
||||||
StringCharAt = 0x12,
|
StringCharAt = 0x12,
|
||||||
StringLength = 0x13,
|
StringLength = 0x13,
|
||||||
StringPushChar = 0x14,
|
StringPushChar = 0x14,
|
||||||
|
StringToInt = 0x15,
|
||||||
ArrayNew = 0x20,
|
ArrayNew = 0x20,
|
||||||
ArraySet = 0x21,
|
ArraySet = 0x21,
|
||||||
ArrayPush = 0x22,
|
ArrayPush = 0x22,
|
||||||
|
@ -9,7 +9,7 @@
|
|||||||
#include <string>
|
#include <string>
|
||||||
#include <vector>
|
#include <vector>
|
||||||
|
|
||||||
bool print_stack_debug = false;
|
bool print_stack_debug = true;
|
||||||
|
|
||||||
int execute_file_and_exit(std::string filename)
|
int execute_file_and_exit(std::string filename)
|
||||||
{
|
{
|
||||||
|
@ -70,6 +70,13 @@ struct Bool {
|
|||||||
};
|
};
|
||||||
struct String {
|
struct String {
|
||||||
std::string value;
|
std::string value;
|
||||||
|
inline auto at(int32_t index) -> int32_t {
|
||||||
|
if (index >= static_cast<int32_t>(this->value.length()) || index < 0) {
|
||||||
|
std::cout << std::format("index not in range, expected to be in range (0..{}), got: {}", this->value.length()-1, index);
|
||||||
|
exit(1);
|
||||||
|
}
|
||||||
|
return this->value.at(index);
|
||||||
|
}
|
||||||
};
|
};
|
||||||
struct Ptr {
|
struct Ptr {
|
||||||
uint32_t value;
|
uint32_t value;
|
||||||
|
@ -285,6 +285,14 @@ void VM::run_builtin(Builtin builtin_id)
|
|||||||
"Running builtin {}\n", static_cast<uint32_t>(builtin_id));
|
"Running builtin {}\n", static_cast<uint32_t>(builtin_id));
|
||||||
}
|
}
|
||||||
switch (builtin_id) {
|
switch (builtin_id) {
|
||||||
|
case Builtin::IntToString: {
|
||||||
|
assert_stack_has(1);
|
||||||
|
auto number = static_cast<int32_t>(stack_pop().as_int().value);
|
||||||
|
auto str = std::to_string(number);
|
||||||
|
stack_push(String(str));
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
case Builtin::StringConcat: {
|
case Builtin::StringConcat: {
|
||||||
assert_stack_has(2);
|
assert_stack_has(2);
|
||||||
auto right = stack_pop();
|
auto right = stack_pop();
|
||||||
@ -303,11 +311,10 @@ void VM::run_builtin(Builtin builtin_id)
|
|||||||
case Builtin::StringCharAt: {
|
case Builtin::StringCharAt: {
|
||||||
assert_stack_has(2);
|
assert_stack_has(2);
|
||||||
auto index_value = stack_pop();
|
auto index_value = stack_pop();
|
||||||
auto str = stack_pop();
|
auto string_value = stack_pop();
|
||||||
|
auto index = static_cast<int32_t>(index_value.as_int().value);
|
||||||
auto index = static_cast<size_t>(index_value.as_int().value);
|
auto string = string_value.as_string();
|
||||||
auto ch = static_cast<int32_t>(str.as_string().value.at(index));
|
stack_push(Int(string.at(index)));
|
||||||
stack_push(Int(ch));
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case Builtin::StringLength: {
|
case Builtin::StringLength: {
|
||||||
@ -328,6 +335,14 @@ void VM::run_builtin(Builtin builtin_id)
|
|||||||
stack_push(String(new_str));
|
stack_push(String(new_str));
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
case Builtin::StringToInt: {
|
||||||
|
assert_stack_has(1);
|
||||||
|
auto str = stack_pop().as_string().value;
|
||||||
|
auto number = atoi(str.c_str());
|
||||||
|
stack_push(Int(number));
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
case Builtin::ArrayNew: {
|
case Builtin::ArrayNew: {
|
||||||
auto alloc_res = this->heap.alloc<heap::AllocType::Array>();
|
auto alloc_res = this->heap.alloc<heap::AllocType::Array>();
|
||||||
stack_push(Ptr(alloc_res.val()));
|
stack_push(Ptr(alloc_res.val()));
|
||||||
@ -335,8 +350,12 @@ void VM::run_builtin(Builtin builtin_id)
|
|||||||
}
|
}
|
||||||
case Builtin::ArraySet: {
|
case Builtin::ArraySet: {
|
||||||
assert_stack_has(2);
|
assert_stack_has(2);
|
||||||
std::cerr << std::format("not implemented\n");
|
auto index = stack_pop().as_int().value;
|
||||||
std::exit(1);
|
auto array_ptr = stack_pop().as_ptr().value;
|
||||||
|
auto value = stack_pop();
|
||||||
|
auto array = this->heap.at(array_ptr).val()->as_array();
|
||||||
|
array.at(index) = value;
|
||||||
|
stack_push(Null());
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case Builtin::ArrayPush: {
|
case Builtin::ArrayPush: {
|
||||||
@ -354,7 +373,7 @@ void VM::run_builtin(Builtin builtin_id)
|
|||||||
auto array_ptr = stack_pop().as_ptr().value;
|
auto array_ptr = stack_pop().as_ptr().value;
|
||||||
|
|
||||||
auto array = this->heap.at(array_ptr).val()->as_array();
|
auto array = this->heap.at(array_ptr).val()->as_array();
|
||||||
stack_push(array.values.at(static_cast<size_t>(index)));
|
stack_push(array.at(index));
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case Builtin::ArrayLength: {
|
case Builtin::ArrayLength: {
|
||||||
|
Loading…
Reference in New Issue
Block a user