]> git.mdlowis.com Git - proto/cerise-c.git/commitdiff
removed runtime lib and implemented string comparisons and string indexing
authorMike Lowis <mike.lowis@gentex.com>
Thu, 24 Oct 2024 17:54:37 +0000 (13:54 -0400)
committerMike Lowis <mike.lowis@gentex.com>
Thu, 24 Oct 2024 17:54:37 +0000 (13:54 -0400)
28 files changed:
build.sh
cerise-c.m
lib/codegen.rb
lib/compiler.rb
lib/lexer.rb
lib/parser.rb
lib/type_checker.rb
runtime.h
runtime/Array.c [deleted file]
runtime/Assert.c [deleted file]
runtime/Dict.c [deleted file]
runtime/Error.c [deleted file]
runtime/GC.c [deleted file]
runtime/Length.c [deleted file]
runtime/Object.c [deleted file]
runtime/OpAdd.c [deleted file]
runtime/OpDiv.c [deleted file]
runtime/OpEq.c [deleted file]
runtime/OpGt.c [deleted file]
runtime/OpGtEq.c [deleted file]
runtime/OpLt.c [deleted file]
runtime/OpLtEq.c [deleted file]
runtime/OpMod.c [deleted file]
runtime/OpMul.c [deleted file]
runtime/OpNeq.c [deleted file]
runtime/OpSub.c [deleted file]
runtime/String.c [deleted file]
runtime/ToString.c [deleted file]

index 2877b46b3f492c265d33de8832d03b01851347e3..caaac5e0d9a112dc675e57438806234e35afef16 100755 (executable)
--- 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
index 666f8ae25ecf0d11c1548e0863ac8b17e33a7aba..d96fb653211b69c3e2e1dc23c05dcede275b10df 100644 (file)
@@ -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()
index c81a83a4007ad47435088782ca0e735d4c3e7524..ebf9be5d2bb6a11e1cce10f296ebfc2d4ca59a2e 100644 (file)
@@ -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
index 6d46483ff00bee87b2fb76a05d1502b4b991eed8..55d2cb44c1021c7c6231d57a116371ee6b94ac40 100644 (file)
@@ -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
index edd375e091218067b578e856ee13b38033783f0a..98c76a33602a1a5b9d3e1b62615d8582a51486d4 100644 (file)
@@ -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)
index 36c42b96e70f98b8eb489ccb30bd92a40b28871b..3ded9bfb61720d7f316dbddfc6a6278d6ce67626 100644 (file)
@@ -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
index 78542aea968064683e9e5916a150f38aac18af8b..9dcd64bd8c7b1d1d40e8b0d0918e4ccf79b8091a 100644 (file)
@@ -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
index d5e3f8d581741ea43dcae83f7ed24714e6a1ee1b..b50568b0cb11dc2e0a7cc6b857f0ceee3a781d73 100644 (file)
--- 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 (file)
index c0f6997..0000000
+++ /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 (file)
index fc6896b..0000000
+++ /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 (file)
index 08dcb79..0000000
+++ /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 (file)
index c74cba7..0000000
+++ /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 (file)
index c39586c..0000000
+++ /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 (file)
index 4ac494f..0000000
+++ /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 (file)
index a85c6b1..0000000
+++ /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 (file)
index 1fd452b..0000000
+++ /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 (file)
index d428d66..0000000
+++ /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 (file)
index 6007357..0000000
+++ /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 (file)
index f11f188..0000000
+++ /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 (file)
index fb415f6..0000000
+++ /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 (file)
index b36bab4..0000000
+++ /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 (file)
index 5a2e8a5..0000000
+++ /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 (file)
index 6a5e361..0000000
+++ /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 (file)
index 456e631..0000000
+++ /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 (file)
index f7bd8d0..0000000
+++ /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 (file)
index d21b07c..0000000
+++ /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 (file)
index c2c2cc6..0000000
+++ /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 (file)
index 453d949..0000000
+++ /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;
-}