everything

This commit is contained in:
Mikkel Kongsted 2024-12-13 16:03:01 +01:00
parent 7c83c7296d
commit 219785e465
13 changed files with 392 additions and 19 deletions

View File

@ -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,

View File

@ -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 {

View File

@ -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();

View File

@ -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",

View 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
View 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
}

View File

@ -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

View File

@ -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>();

View File

@ -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 {

View File

@ -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,

View File

@ -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)
{

View File

@ -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;

View File

@ -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: {