From bd41924f3df1edbcf66d1afac0caabf70a25cd1f Mon Sep 17 00:00:00 2001 From: Mike Lowis Date: Thu, 24 Oct 2024 13:54:37 -0400 Subject: [PATCH] removed runtime lib and implemented string comparisons and string indexing --- build.sh | 27 ++--------- cerise-c.m | 34 +++++++------- lib/codegen.rb | 36 +++++++++++---- lib/compiler.rb | 2 +- lib/lexer.rb | 3 ++ lib/parser.rb | 2 + lib/type_checker.rb | 9 +++- runtime.h | 106 ++++++++++++++++++++++++++++++++++++++------ runtime/Array.c | 39 ---------------- runtime/Assert.c | 8 ---- runtime/Dict.c | 78 -------------------------------- runtime/Error.c | 11 ----- runtime/GC.c | 21 --------- runtime/Length.c | 15 ------- runtime/Object.c | 27 ----------- runtime/OpAdd.c | 29 ------------ runtime/OpDiv.c | 14 ------ runtime/OpEq.c | 17 ------- runtime/OpGt.c | 13 ------ runtime/OpGtEq.c | 13 ------ runtime/OpLt.c | 13 ------ runtime/OpLtEq.c | 13 ------ runtime/OpMod.c | 12 ----- runtime/OpMul.c | 14 ------ runtime/OpNeq.c | 17 ------- runtime/OpSub.c | 14 ------ runtime/String.c | 20 --------- runtime/ToString.c | 23 ---------- 28 files changed, 152 insertions(+), 478 deletions(-) delete mode 100644 runtime/Array.c delete mode 100644 runtime/Assert.c delete mode 100644 runtime/Dict.c delete mode 100644 runtime/Error.c delete mode 100644 runtime/GC.c delete mode 100644 runtime/Length.c delete mode 100644 runtime/Object.c delete mode 100644 runtime/OpAdd.c delete mode 100644 runtime/OpDiv.c delete mode 100644 runtime/OpEq.c delete mode 100644 runtime/OpGt.c delete mode 100644 runtime/OpGtEq.c delete mode 100644 runtime/OpLt.c delete mode 100644 runtime/OpLtEq.c delete mode 100644 runtime/OpMod.c delete mode 100644 runtime/OpMul.c delete mode 100644 runtime/OpNeq.c delete mode 100644 runtime/OpSub.c delete mode 100644 runtime/String.c delete mode 100644 runtime/ToString.c diff --git a/build.sh b/build.sh index 2877b46..caaac5e 100755 --- a/build.sh +++ b/build.sh @@ -3,28 +3,7 @@ OPTLEVEL=1 # cleanup old files -rm -f cerise-c libruntime.a runtime/*.o - -# compile all runtime sources -for f in runtime/*.c; do - printf "CC %s\n" "$f" - gcc -c -I. -O$OPTLEVEL -o "${f%.c}.o" "$f" & -done -wait - -# compile the static lib -printf "LIB %s\n" libruntime.a -ar rcs libruntime.a runtime/*.o - -# generate and compile the main function -printf "#include \"runtime.h\"\nENTRYPOINT(%s)\n" TestSuite_Main > main.c -gcc -c -I. -O$OPTLEVEL -o main.o main.c - -# now compile the cerise file and link -printf "\n" -./cerise-c.rb > cerise-c.c \ - && gcc -I. -O$optlevel -o cerise-c main.o cerise-c.o libruntime.a \ - && size cerise-c \ - && printf "\n" \ - && ./cerise-c +rm -f cerise-c +# run the compiler and resulting binary +./cerise-c.rb cerise-c.m && ./cerise-c diff --git a/cerise-c.m b/cerise-c.m index 666f8ae..d96fb65 100644 --- a/cerise-c.m +++ b/cerise-c.m @@ -6,16 +6,6 @@ imports ( exports (Main) -TestLiterals() -{ -# assert 42 -# assert 42.0 - assert true - #assert false - #assert nil -# assert "123" -} - TestBoolOps() { assert true == true @@ -86,7 +76,11 @@ TestStringOps() { assert "foo" == "foo" assert "foo" != "bar" -# assert ("foo" + "bar") == "foobar" + assert ("foo" + "bar") == "foobar" + assert("foo"[0] == 'f') + + + # assert ("foo" + 123) == "foo123" # assert ("foo" + 123.0) == "foo123.000000" # assert ("foo" + true) == "footrue" @@ -117,7 +111,7 @@ TestHashOps() TestEqOps() { assert ("" == "") == true - assert ("" == "a") == true + assert ("" != "a") == true assert (1 == 1) == true assert (1 == 2) == false assert (1.0 == 1.0) == true @@ -131,11 +125,16 @@ TestEqOps() { } TestNeqOps() { -# assert ("" != "") == false -# assert ("" != 1) == true -# assert ("" != 1.0) == true -# assert ("" != true) == true -# assert ("" != false) == true + assert ("" != "") == false + assert ("" != "a") == true + assert (1 != 1) == false + assert (2 != 1) == true + assert (1.0 != 1.0) == false + assert (2.0 != 1.0) == true + assert (true != true) == false + assert (false != false) == false + assert (true != false) == true + assert (false != true) == true # assert ("" != []) == true # assert ("" != {}) == true } @@ -196,7 +195,6 @@ AddTwoNums(a : int, b : int) Main() { AddTwoNums(1,2) + 5 - TestLiterals() TestBoolOps() TestIntOps() TestRealOps() diff --git a/lib/codegen.rb b/lib/codegen.rb index c81a83a..ebf9be5 100644 --- a/lib/codegen.rb +++ b/lib/codegen.rb @@ -15,7 +15,9 @@ class Codegen end def type_to_s(type) - if type.is_a? Symbol + if type == :string + "_string" + elsif type.is_a? Symbol type elsif type.form == :array "_array" @@ -104,18 +106,18 @@ class Codegen elsif v.value == true || v.value == false putln "#{type} #{var} = (#{v.value});" elsif v.value.is_a? String - putln "#{type} #{var} = MakeString(#{v.value});" + putln "#{type} #{var} = String_Create(#{v.value}, #{v.value.length-2});" elsif v.value.is_a? Array - putln "#{type} #{var} = MakeArray(#{v.value.length});" + putln "#{type} #{var} = Array_Create(#{v.value.length});" v.value.each_with_index do |e, i| val = emit(e) putln "Array_Set(#{var}, #{i}, #{val});" end elsif v.value.is_a? Hash - putln "Value #{var} = MakeDict(#{v.value.length});" + putln "Value #{var} = Dictionary_Create(#{v.value.length});" v.value.each do |k, v| val = emit(v) - putln "Dict_Set(#{var}, MakeString(#{k.value}), #{val});" + putln "Dict_Set(#{var}, String_Create(#{k.value}), #{val});" end else raise "code emitting constants of this type not implemented" @@ -158,14 +160,22 @@ class Codegen lvar = emit(v.left) rvar = emit(v.right) result = mktemp(); - putln "#{type} #{result} = Object_Get(#{lvar}, #{rvar});" + if v.left.type == :string + putln "#{type} #{result} = String_Get(#{lvar}, #{rvar});" + else + putln "#{type} #{result} = Array_Get(#{lvar}, #{rvar});" + end else lvar = emit(v.left) rvar = emit(v.right) result = mktemp(); case v.op when "+" - putln "#{type} #{result} = (#{lvar} + #{rvar});" + if v.type == :string + putln "#{type} #{result} = String_Concat(#{lvar}, #{rvar});" + else + putln "#{type} #{result} = (#{lvar} + #{rvar});" + end when "-" putln "#{type} #{result} = (#{lvar} - #{rvar});" when "*" @@ -183,9 +193,17 @@ class Codegen when ">=" putln "#{type} #{result} = (#{lvar} >= #{rvar});" when "==" - putln "#{type} #{result} = (#{lvar} == #{rvar});" + if v.left.type == :string + putln "#{type} #{result} = (0 == String_Compare(#{lvar}, #{rvar}));" + else + putln "#{type} #{result} = (#{lvar} == #{rvar});" + end when "!=" - putln "#{type} #{result} = (#{lvar} != #{rvar});" + if v.left.type == :string + putln "#{type} #{result} = (0 != String_Compare(#{lvar}, #{rvar}));" + else + putln "#{type} #{result} = (#{lvar} != #{rvar});" + end else raise "not implemented" end diff --git a/lib/compiler.rb b/lib/compiler.rb index 6d46483..55d2cb4 100644 --- a/lib/compiler.rb +++ b/lib/compiler.rb @@ -45,7 +45,7 @@ module Compiler f.puts "ENTRYPOINT(#{mod.name}_Main)" end `gcc -c -I. -O1 -o main.o main.c` - `gcc -I. -O1 -o #{binname} #{deps.join(" ")} main.o libruntime.a` + `gcc -I. -O1 -o #{binname} #{deps.join(" ")} main.o` end end end \ No newline at end of file diff --git a/lib/lexer.rb b/lib/lexer.rb index edd375e..98c76a3 100644 --- a/lib/lexer.rb +++ b/lib/lexer.rb @@ -31,6 +31,7 @@ class Lexer INTEGER = /[0-9]+/ FLOATING = /[0-9]+\.[0-9]+/ STRING = /"(\\"|[^"])*"/ + CHAR = /'(\\'|[^'])'/ ID_TYPES = { "true" => :bool, "false" => :bool, @@ -59,6 +60,8 @@ class Lexer type = :int elsif @data.scan(STRING) type = :string + elsif @data.scan(CHAR) + type = :char elsif @data.scan(BRACES) type = @data.matched elsif @data.scan(OPERATORS) diff --git a/lib/parser.rb b/lib/parser.rb index 36c42b9..3ded9bf 100644 --- a/lib/parser.rb +++ b/lib/parser.rb @@ -443,6 +443,8 @@ class Parser IR::Const.new(tok.pos, :string, tok.text) elsif tok.type == :int IR::Const.new(tok.pos, :int, tok.text.to_i) + elsif tok.type == :char + IR::Const.new(tok.pos, :int, tok.text[1].ord) elsif tok.type == :float IR::Const.new(tok.pos, :float, tok.text.to_f) elsif tok.type == :void diff --git a/lib/type_checker.rb b/lib/type_checker.rb index 78542ae..9dcd64b 100644 --- a/lib/type_checker.rb +++ b/lib/type_checker.rb @@ -382,10 +382,15 @@ class TypeChecker def check_binary(env, expr, vtype) if expr.op == "[" left_type = infer(env, expr.left) - if (left_type.is_a? Value::Type) and left_type.form == :array + if left_type == :string + check(env, expr.right, :int) + expr.type = :int + elsif not (left_type.is_a? Value::Type) + error(expr.loc, "type '#{left_type}' is not indexable") + elsif left_type.form == :array check(env, expr.right, :int) expr.type = left_type.base - elsif (left_type.is_a? Value::Type) and left_type.form == :hash + elsif left_type.form == :hash check(env, expr.right, left_type.base[0]) expr.type = left_type.base[1] else diff --git a/runtime.h b/runtime.h index d5e3f8d..b50568b 100644 --- a/runtime.h +++ b/runtime.h @@ -9,10 +9,10 @@ typedef intptr_t _value; -typedef struct string { +typedef struct _string { uint64_t length; uint8_t bytes[]; -}* string; +}* _string; typedef struct array { uint64_t length; @@ -20,33 +20,113 @@ typedef struct array { _value* values; }* _array; -typedef struct dict_node { - struct dict_node* left; - struct dict_node* right; +typedef struct _dict_node { + struct _dict_node* left; + struct _dict_node* right; _value key; _value value; uint32_t hash; -}* dict_node; +}* _dict_node; typedef struct dict { uint64_t length; - dict_node root; + _dict_node root; }* _dict; -string MakeString(char* s); -_array MakeArray(int32_t nslots); -_dict MakeDict(int32_t nslots); -void Assert(char* file, int lineno, bool val); +/* Runtime Errors + *************************************************/ + +static inline void RuntimeError(char* s) +{ + fprintf(stderr, "fatal error: %s\n", s); + exit(1); +} + +static inline void Assert(char* file, int lineno, bool val) +{ + if (!val) { + fprintf(stderr, "%s:%d:error: Assertion failed\n", file, lineno); + exit(1); + } +} + +/* Strings + *************************************************/ + +#pragma GCC diagnostic push +#pragma GCC diagnostic ignored "-Wshift-count-overflow" + +static inline _array Array_Create(int32_t nslots) +{ + _array array = calloc(1, sizeof(struct array)); + array->length = nslots; + nslots--; + nslots |= nslots >> 1; + nslots |= nslots >> 2; + nslots |= nslots >> 4; + nslots |= nslots >> 8; + nslots |= nslots >> 16; + nslots |= nslots >> 32; + nslots++; + array->capacity = nslots; + array->values = calloc(array->capacity, sizeof(_value)); + return array; +} + +#pragma GCC diagnostic pop static inline void Array_Set(_array ary, int index, _value val) { + if (index >= ary->length) { + RuntimeError("array index out of bounds"); + } + ary->values[index] = val; } -/* Garbage Collection +static inline _value Array_Get(_array ary, int index) +{ + if (index >= ary->length) { + RuntimeError("array index out of bounds"); + } + return ary->values[index]; +} + +/* Strings *************************************************/ -void* GC_Allocate(size_t nbytes); +static inline _string String_Create(char* s, size_t len) +{ + _string str = malloc(sizeof(_string) + len + 1); + memcpy(str->bytes, s, len+1); + str->length = len; + return str; +} + +static inline _value String_Get(_string str, int index) +{ + if (index >= str->length) + { + RuntimeError("string index out of bounds"); + } + return str->bytes[index]; +} + +static inline _string String_Concat(_string a, _string b) +{ + _string str = malloc(sizeof(_string) + a->length + b->length + 1); + memcpy(str->bytes, a->bytes, a->length); + memcpy(&(str->bytes[a->length]), b->bytes, b->length + 1); + str->length = a->length + b->length; + return str; +} + +static inline _value String_Compare(_string a, _string b) +{ + return strcmp(a->bytes, b->bytes); +} +/* Program Entry Point Definition + *************************************************/ #define ENTRYPOINT(func) \ int main(int argc, char** argv) { \ diff --git a/runtime/Array.c b/runtime/Array.c deleted file mode 100644 index c0f6997..0000000 --- a/runtime/Array.c +++ /dev/null @@ -1,39 +0,0 @@ -#include "runtime.h" - -static uint64_t NextPow2(uint64_t val) { - val--; - val |= val >> 1; - val |= val >> 2; - val |= val >> 4; - val |= val >> 8; - val |= val >> 16; - val |= val >> 32; - val++; - return val; -} - -Value MakeArray(int32_t nslots) { - Array* array = GC_Allocate(sizeof(Array)); - array->length = nslots; - array->capacity = NextPow2(nslots); - array->values = GC_Allocate(nslots * sizeof(Value)); - return (Value){ .as_uint64 = (NAN_TAG_ARRAY | (uintptr_t)array) }; -} - -void Array_Set(Value array, int index, Value value) -{ - Array* ary = ValueAsArray(array); - if (index >= ary->length) { - RuntimeError("array index out of bounds"); - } - ary->values[index] = value; -} - -Value Array_Get(Value array, int index) -{ - Array* ary = ValueAsArray(array); - if (index >= ary->length) { - RuntimeError("array index out of bounds"); - } - return ary->values[index]; -} diff --git a/runtime/Assert.c b/runtime/Assert.c deleted file mode 100644 index fc6896b..0000000 --- a/runtime/Assert.c +++ /dev/null @@ -1,8 +0,0 @@ -#include "runtime.h" - -void Assert(char* file, int lineno, Value val) { - if (IsFalse(val) || IsNil(val)) { - fprintf(stderr, "%s:%d:error: Assertion failed\n", file, lineno); - exit(1); - } -} diff --git a/runtime/Dict.c b/runtime/Dict.c deleted file mode 100644 index 08dcb79..0000000 --- a/runtime/Dict.c +++ /dev/null @@ -1,78 +0,0 @@ -#include "runtime.h" - -static uint32_t Hash(Value val) { - String* string = ValueAsString(val); - char* key = string->bytes; - uint32_t a=31415u, b=27183u, hash; - for (hash=0; *key; key++, a *= b) { - hash = (a * hash) + *key; - } - hash = (hash + 0x7ed55d16) + (hash << 12); - hash = (hash ^ 0xc761c23c) ^ (hash >> 19); - hash = (hash + 0x165667b1) + (hash << 5); - hash = (hash + 0xd3a2646c) ^ (hash << 9); - hash = (hash + 0xfd7046c5) + (hash << 3); - hash = (hash ^ 0xb55a4f09) ^ (hash >> 16); - return hash; -} - -static int CompareNode(DictNode* left, DictNode* right) { - int cmp = left->hash - right->hash; - if (cmp == 0) { - cmp = ValueAsBool(OpEq(left->key, right->key)) ? 0 : 1; - } - return cmp; -} - -static DictNode** FindNode(DictNode** root, DictNode* node) { - DictNode** curr = root; - while(*curr != NULL) { - int cmp = CompareNode(node, *curr); - if (cmp < 0) - curr = &((*curr)->left); - else if (cmp > 0) - curr = &((*curr)->right); - else - break; - } - return curr; -} - -Value MakeDict(int32_t nslots) { - Dict* dict = GC_Allocate(sizeof(Dict)); - return (Value){ .as_uint64 = (NAN_TAG_DICT | (uintptr_t)dict) }; -} - -void Dict_Set(Value dictionary, Value key, Value value) -{ - DictNode node = { - .hash = Hash(key), - .key = key, - .value = value - }; - Dict* dict = ValueAsDict(dictionary); - DictNode** curr = FindNode(&(dict->root), &node); - if (!*curr) { - DictNode* new_node = GC_Allocate(sizeof(DictNode)); - *new_node = node; - *curr = new_node; - dict->length++; - } else { - (*curr)->value = value; - } -} - -Value Dict_Get(Value dictionary, Value key) -{ - DictNode node = { - .hash = Hash(key), - .key = key, - }; - Dict* dict = ValueAsDict(dictionary); - DictNode** curr = FindNode(&(dict->root), &node); - Value result = MakeNil(); - if (*curr) { - result = (*curr)->value; - } - return result; -} diff --git a/runtime/Error.c b/runtime/Error.c deleted file mode 100644 index c74cba7..0000000 --- a/runtime/Error.c +++ /dev/null @@ -1,11 +0,0 @@ -#include "runtime.h" - -Value Error(Value val) { - RuntimeError(ValueAsString(val)->bytes); - return MakeNil(); -} - -void RuntimeError(char* s) { - fprintf(stderr, "fatal error: %s\n", s); - exit(1); -} diff --git a/runtime/GC.c b/runtime/GC.c deleted file mode 100644 index c39586c..0000000 --- a/runtime/GC.c +++ /dev/null @@ -1,21 +0,0 @@ -#include "runtime.h" - -#define FIRST_GEN_SIZE ((1024*1024) / sizeof(Value)) - -Value First_Gen_Heap[FIRST_GEN_SIZE]; -Value* Heap_Next = First_Gen_Heap; -Value* Heap_End = First_Gen_Heap + FIRST_GEN_SIZE; - -void* GC_Allocate(size_t nbytes) { - size_t ncells = nbytes / sizeof(Value); - if ((nbytes - (ncells * sizeof(Value))) > 0) { - ncells++; - } - Value* obj = Heap_Next; - Heap_Next += ncells; - if (Heap_Next > Heap_End) { - fprintf(stderr, "out of memory"); - exit(1); - } - return obj; -} diff --git a/runtime/Length.c b/runtime/Length.c deleted file mode 100644 index 4ac494f..0000000 --- a/runtime/Length.c +++ /dev/null @@ -1,15 +0,0 @@ -#include "runtime.h" - -Value Length(Value val) { - Value result = MakeInt(0); - if (IsDict(val)) { - result = MakeInt( ValueAsDict(val)->length ); - } else if (IsArray(val)) { - result = MakeInt( ValueAsArray(val)->length ); - } else if (IsString(val)) { - result = MakeInt( ValueAsString(val)->length ); - } else { - RuntimeError("value is not an aggregate type"); - } - return result; -} diff --git a/runtime/Object.c b/runtime/Object.c deleted file mode 100644 index a85c6b1..0000000 --- a/runtime/Object.c +++ /dev/null @@ -1,27 +0,0 @@ -#include "runtime.h" - -Value Object_Get(Value object, Value key) -{ - Value result = MakeNil(); - if (IsDict(object)) { - result = Dict_Get(object, key); - } else if (IsArray(object)) { - result = Array_Get(object, ValueAsInt(key)); - } else if (IsString(object)) { - result = String_Get(object, ValueAsInt(key)); - } else { - RuntimeError("object is not indexable"); - } - return result; -} - -void Object_Set(Value object, Value key, Value value) -{ - if (IsDict(object)) { - Dict_Set(object, key, value); - } else if (IsArray(object)) { - Array_Set(object, ValueAsInt(key), value); - } else { - RuntimeError("object is not assignable"); - } -} diff --git a/runtime/OpAdd.c b/runtime/OpAdd.c deleted file mode 100644 index 1fd452b..0000000 --- a/runtime/OpAdd.c +++ /dev/null @@ -1,29 +0,0 @@ -#include "runtime.h" - -Value OpAdd(Value left, Value right) { - Value result; - if (IsInt(left)) { - result = MakeInt(ValueAsInt(left) + ValueAsInt(right)); - } else if (IsReal(left)) { - result = MakeReal(ValueAsReal(left) + ValueAsReal(right)); - } else if (IsString(left)) { - right = ToString(right); - String* left_str = ValueAsString(left); - String* right_str = ValueAsString(right); - size_t sz = left_str->length + right_str->length; - String* str = GC_Allocate(sizeof(String) + sz + 1); - str->length = sz; - memcpy( - str->bytes, - left_str->bytes, - left_str->length); - memcpy( - &str->bytes[left_str->length], - right_str->bytes, - right_str->length + 1); - result = (Value){ .as_uint64 = (NAN_TAG_STRING | (uint64_t)str) }; - } else { - RuntimeError("addition operator used on invalid type"); - } - return result; -} diff --git a/runtime/OpDiv.c b/runtime/OpDiv.c deleted file mode 100644 index d428d66..0000000 --- a/runtime/OpDiv.c +++ /dev/null @@ -1,14 +0,0 @@ -#include "runtime.h" - -Value OpDiv(Value left, Value right) { - Value result; - if (IsInt(left)) { - result = MakeInt(ValueAsInt(left) / ValueAsInt(right)); - } else if (IsReal(left)) { - result = MakeReal(ValueAsReal(left) / ValueAsReal(right)); - } else { - fprintf(stderr, "fatal error: addition operator used on invalid type\n"); - exit(1); - } - return result; -} diff --git a/runtime/OpEq.c b/runtime/OpEq.c deleted file mode 100644 index 6007357..0000000 --- a/runtime/OpEq.c +++ /dev/null @@ -1,17 +0,0 @@ -#include "runtime.h" - -Value OpEq(Value left, Value right) { - Value result; - if (IsBool(left) && IsBool(right)) { - result = MakeBool(ValueAsBool(left) == ValueAsBool(right)); - } else if (IsInt(left) && IsInt(right)) { - result = MakeBool(ValueAsInt(left) == ValueAsInt(right)); - } else if (IsReal(left) && IsReal(right)) { - result = MakeBool(ValueAsReal(left) == ValueAsReal(right)); - } else if (IsString(left) && IsString(right)) { - result = MakeBool(!strcmp(ValueAsString(left)->bytes, ValueAsString(right)->bytes)); - } else { - result = MakeBool(false); - } - return result; -} diff --git a/runtime/OpGt.c b/runtime/OpGt.c deleted file mode 100644 index f11f188..0000000 --- a/runtime/OpGt.c +++ /dev/null @@ -1,13 +0,0 @@ -#include "runtime.h" - -Value OpGt(Value left, Value right) { - Value result; - if (IsInt(left) && IsInt(right)) { - result = MakeBool(ValueAsInt(left) > ValueAsInt(right)); - } else if (IsReal(left) && IsReal(right)) { - result = MakeBool(ValueAsReal(left) > ValueAsReal(right)); - } else { - result = MakeBool(false); - } - return result; -} diff --git a/runtime/OpGtEq.c b/runtime/OpGtEq.c deleted file mode 100644 index fb415f6..0000000 --- a/runtime/OpGtEq.c +++ /dev/null @@ -1,13 +0,0 @@ -#include "runtime.h" - -Value OpGtEq(Value left, Value right) { - Value result; - if (IsInt(left)) { - result = MakeBool(ValueAsInt(left) >= ValueAsInt(right)); - } else if (IsReal(left)) { - result = MakeBool(ValueAsReal(left) >= ValueAsReal(right)); - } else { - result = MakeBool(false); - } - return result; -} diff --git a/runtime/OpLt.c b/runtime/OpLt.c deleted file mode 100644 index b36bab4..0000000 --- a/runtime/OpLt.c +++ /dev/null @@ -1,13 +0,0 @@ -#include "runtime.h" - -Value OpLt(Value left, Value right) { - Value result; - if (IsInt(left) && IsInt(right)) { - result = MakeBool(ValueAsInt(left) < ValueAsInt(right)); - } else if (IsReal(left) && IsReal(right)) { - result = MakeBool(ValueAsReal(left) < ValueAsReal(right)); - } else { - result = MakeBool(false); - } - return result; -} diff --git a/runtime/OpLtEq.c b/runtime/OpLtEq.c deleted file mode 100644 index 5a2e8a5..0000000 --- a/runtime/OpLtEq.c +++ /dev/null @@ -1,13 +0,0 @@ -#include "runtime.h" - -Value OpLtEq(Value left, Value right) { - Value result; - if (IsInt(left) && IsInt(right)) { - result = MakeBool(ValueAsInt(left) <= ValueAsInt(right)); - } else if (IsReal(left) && IsReal(right)) { - result = MakeBool(ValueAsReal(left) <= ValueAsReal(right)); - } else { - result = MakeBool(false); - } - return result; -} diff --git a/runtime/OpMod.c b/runtime/OpMod.c deleted file mode 100644 index 6a5e361..0000000 --- a/runtime/OpMod.c +++ /dev/null @@ -1,12 +0,0 @@ -#include "runtime.h" - -Value OpMod(Value left, Value right) { - Value result; - if (IsInt(left)) { - result = MakeInt(ValueAsInt(left) % ValueAsInt(right)); - } else { - fprintf(stderr, "fatal error: addition operator used on invalid type\n"); - exit(1); - } - return result; -} diff --git a/runtime/OpMul.c b/runtime/OpMul.c deleted file mode 100644 index 456e631..0000000 --- a/runtime/OpMul.c +++ /dev/null @@ -1,14 +0,0 @@ -#include "runtime.h" - -Value OpMul(Value left, Value right) { - Value result; - if (IsInt(left)) { - result = MakeInt(ValueAsInt(left) * ValueAsInt(right)); - } else if (IsReal(left)) { - result = MakeReal(ValueAsReal(left) * ValueAsReal(right)); - } else { - fprintf(stderr, "fatal error: addition operator used on invalid type\n"); - exit(1); - } - return result; -} diff --git a/runtime/OpNeq.c b/runtime/OpNeq.c deleted file mode 100644 index f7bd8d0..0000000 --- a/runtime/OpNeq.c +++ /dev/null @@ -1,17 +0,0 @@ -#include "runtime.h" - -Value OpNeq(Value left, Value right) { - Value result; - if (IsBool(left) && IsBool(right)) { - result = MakeBool(ValueAsBool(left) != ValueAsBool(right)); - } else if (IsInt(left) && IsInt(right)) { - result = MakeBool(ValueAsInt(left) != ValueAsInt(right)); - } else if (IsReal(left) && IsReal(right)) { - result = MakeBool(ValueAsReal(left) != ValueAsReal(right)); - } else if (IsString(left) && IsString(right)) { - result = MakeBool(0 != strcmp(ValueAsString(left)->bytes, ValueAsString(right)->bytes)); - } else { - result = MakeBool(true); - } - return result; -} diff --git a/runtime/OpSub.c b/runtime/OpSub.c deleted file mode 100644 index d21b07c..0000000 --- a/runtime/OpSub.c +++ /dev/null @@ -1,14 +0,0 @@ -#include "runtime.h" - -Value OpSub(Value left, Value right) { - Value result; - if (IsInt(left)) { - result = MakeInt(ValueAsInt(left) - ValueAsInt(right)); - } else if (IsReal(left)) { - result = MakeReal(ValueAsReal(left) - ValueAsReal(right)); - } else { - fprintf(stderr, "fatal error: addition operator used on invalid type\n"); - exit(1); - } - return result; -} diff --git a/runtime/String.c b/runtime/String.c deleted file mode 100644 index c2c2cc6..0000000 --- a/runtime/String.c +++ /dev/null @@ -1,20 +0,0 @@ -#include "runtime.h" - -Value MakeString(char* s) { - size_t sz = strlen(s); - String* str = GC_Allocate(sizeof(String) + sz + 1); - str->length = sz; - strncpy(str->bytes, s, sz+1); - Value ret = (Value){ .as_uint64 = (NAN_TAG_STRING | (uint64_t)str) }; - assert(IsString(ret)); - return ret; -} - -Value String_Get(Value hash, int index) -{ - String* str = ValueAsString(hash); - if (index >= str->length) { - RuntimeError("string index out of bounds"); - } - return MakeInt( str->bytes[index] ); -} diff --git a/runtime/ToString.c b/runtime/ToString.c deleted file mode 100644 index 453d949..0000000 --- a/runtime/ToString.c +++ /dev/null @@ -1,23 +0,0 @@ -#include "runtime.h" - -Value ToString(Value val) { - Value retval; - if (IsString(val)) { - retval = val; - } else if (IsNil(val)) { - retval = MakeString("nil"); - } else if (IsBool(val)) { - retval = MakeString(IsTrue(val) ? "true" : "false"); - } else if (IsInt(val)) { - char str[64]; - snprintf(str, sizeof(str), "%d", ValueAsInt(val)); - retval = MakeString(str); - } else if (IsReal(val)) { - char str[64]; - snprintf(str, sizeof(str), "%f", ValueAsReal(val)); - retval = MakeString(str); - } else { - assert(!"could not convert string"); - } - return retval; -} -- 2.54.0