mirror of
https://git.sfja.dk/Mikkel/slige.git
synced 2025-01-18 07:46:32 +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 const Builtins = {
|
||||
IntToString: 0x00,
|
||||
StringConcat: 0x10,
|
||||
StringEqual: 0x11,
|
||||
StringCharAt: 0x12,
|
||||
StringLength: 0x13,
|
||||
StringPushChar: 0x14,
|
||||
StringToInt: 0x15,
|
||||
ArrayNew: 0x20,
|
||||
ArraySet: 0x21,
|
||||
ArrayPush: 0x22,
|
||||
|
@ -198,8 +198,8 @@ export class Checker {
|
||||
}
|
||||
case "index": {
|
||||
const subject = this.checkExpr(stmt.kind.subject.kind.subject);
|
||||
if (subject.type !== "array") {
|
||||
this.report("cannot index on non-array", pos);
|
||||
if (subject.type !== "array" && subject.type !== "string") {
|
||||
this.report(`cannot index on non-array, got: ${subject.type}`, pos);
|
||||
return { type: "error" };
|
||||
}
|
||||
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);
|
||||
return { type: "error" };
|
||||
}
|
||||
if (!vtypesEqual(subject.inner, value)) {
|
||||
if (subject.type == "array" && !vtypesEqual(subject.inner, value)) {
|
||||
this.report(
|
||||
`cannot assign incompatible type to array ` +
|
||||
`'${vtypeToString(subject)}'` +
|
||||
@ -345,8 +345,8 @@ export class Checker {
|
||||
}
|
||||
const pos = expr.pos;
|
||||
const subject = this.checkExpr(expr.kind.subject);
|
||||
if (subject.type !== "array") {
|
||||
this.report("cannot index on non-array", pos);
|
||||
if (subject.type !== "array" && subject.type !== "string") {
|
||||
this.report(`cannot index on non-array, got: ${subject.type}`, pos);
|
||||
return { type: "error" };
|
||||
}
|
||||
const value = this.checkExpr(expr.kind.value);
|
||||
@ -354,7 +354,10 @@ export class Checker {
|
||||
this.report("cannot index on array with non-int", pos);
|
||||
return { type: "error" };
|
||||
}
|
||||
return subject.inner;
|
||||
if (subject.type === "array") {
|
||||
return subject.inner;
|
||||
}
|
||||
return { type: "int" }
|
||||
}
|
||||
|
||||
public checkCallExpr(expr: Expr): VType {
|
||||
|
@ -224,7 +224,7 @@ export class Lowerer {
|
||||
case "field":
|
||||
break;
|
||||
case "index":
|
||||
break;
|
||||
return this.lowerIndexExpr(expr);
|
||||
case "call":
|
||||
return this.lowerCallExpr(expr);
|
||||
case "unary":
|
||||
@ -241,6 +241,24 @@ export class Lowerer {
|
||||
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) {
|
||||
if (expr.kind.type !== "sym") {
|
||||
throw new Error();
|
||||
|
@ -1,4 +1,5 @@
|
||||
{
|
||||
<<<<<<< HEAD
|
||||
"$schema": "https://raw.githubusercontent.com/martinring/tmlanguage/master/tmlanguage.json",
|
||||
"name": "Slige",
|
||||
"patterns": [
|
||||
@ -12,6 +13,83 @@
|
||||
],
|
||||
"repository": {
|
||||
"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": [
|
||||
{
|
||||
"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 = \
|
||||
-std=c++23 \
|
||||
-Og \
|
||||
-fsanitize=address,undefined \
|
||||
-Og \
|
||||
-pedantic -pedantic-errors \
|
||||
-Wall -Wextra -Wpedantic -Wconversion \
|
||||
-Wall -Wextra -Wpedantic -Wconversion -Werror \
|
||||
|
||||
|
||||
OUT=build/sliger
|
||||
|
||||
|
@ -38,7 +38,7 @@ private:
|
||||
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>
|
||||
{
|
||||
auto& obj = value->as<sliger::json::Object>();
|
||||
|
@ -13,6 +13,13 @@ namespace sliger::heap {
|
||||
|
||||
struct Array {
|
||||
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 {
|
||||
|
@ -39,11 +39,13 @@ enum class Op : uint32_t {
|
||||
};
|
||||
|
||||
enum class Builtin : uint32_t {
|
||||
IntToString = 0x00,
|
||||
StringConcat = 0x10,
|
||||
StringEqual = 0x11,
|
||||
StringCharAt = 0x12,
|
||||
StringLength = 0x13,
|
||||
StringPushChar = 0x14,
|
||||
StringToInt = 0x15,
|
||||
ArrayNew = 0x20,
|
||||
ArraySet = 0x21,
|
||||
ArrayPush = 0x22,
|
||||
|
@ -9,7 +9,7 @@
|
||||
#include <string>
|
||||
#include <vector>
|
||||
|
||||
bool print_stack_debug = false;
|
||||
bool print_stack_debug = true;
|
||||
|
||||
int execute_file_and_exit(std::string filename)
|
||||
{
|
||||
|
@ -70,6 +70,13 @@ struct Bool {
|
||||
};
|
||||
struct String {
|
||||
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 {
|
||||
uint32_t value;
|
||||
|
@ -285,6 +285,14 @@ void VM::run_builtin(Builtin builtin_id)
|
||||
"Running builtin {}\n", static_cast<uint32_t>(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: {
|
||||
assert_stack_has(2);
|
||||
auto right = stack_pop();
|
||||
@ -303,11 +311,10 @@ void VM::run_builtin(Builtin builtin_id)
|
||||
case Builtin::StringCharAt: {
|
||||
assert_stack_has(2);
|
||||
auto index_value = stack_pop();
|
||||
auto str = stack_pop();
|
||||
|
||||
auto index = static_cast<size_t>(index_value.as_int().value);
|
||||
auto ch = static_cast<int32_t>(str.as_string().value.at(index));
|
||||
stack_push(Int(ch));
|
||||
auto string_value = stack_pop();
|
||||
auto index = static_cast<int32_t>(index_value.as_int().value);
|
||||
auto string = string_value.as_string();
|
||||
stack_push(Int(string.at(index)));
|
||||
break;
|
||||
}
|
||||
case Builtin::StringLength: {
|
||||
@ -328,6 +335,14 @@ void VM::run_builtin(Builtin builtin_id)
|
||||
stack_push(String(new_str));
|
||||
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: {
|
||||
auto alloc_res = this->heap.alloc<heap::AllocType::Array>();
|
||||
stack_push(Ptr(alloc_res.val()));
|
||||
@ -335,8 +350,12 @@ void VM::run_builtin(Builtin builtin_id)
|
||||
}
|
||||
case Builtin::ArraySet: {
|
||||
assert_stack_has(2);
|
||||
std::cerr << std::format("not implemented\n");
|
||||
std::exit(1);
|
||||
auto index = stack_pop().as_int().value;
|
||||
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;
|
||||
}
|
||||
case Builtin::ArrayPush: {
|
||||
@ -354,7 +373,7 @@ void VM::run_builtin(Builtin builtin_id)
|
||||
auto array_ptr = stack_pop().as_ptr().value;
|
||||
|
||||
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;
|
||||
}
|
||||
case Builtin::ArrayLength: {
|
||||
|
Loading…
Reference in New Issue
Block a user