]> git.mdlowis.com Git - proto/cerise-c.git/commitdiff
reworked memory allocations and error messaging
authorMike Lowis <mike.lowis@gentex.com>
Thu, 20 Jun 2024 14:31:31 +0000 (10:31 -0400)
committerMike Lowis <mike.lowis@gentex.com>
Thu, 20 Jun 2024 14:31:31 +0000 (10:31 -0400)
.gitignore
build.sh
cerise-c.rb
runtime.h
runtime/Array.c
runtime/Dict.c
runtime/Error.c
runtime/GC.c [new file with mode: 0644]
runtime/Object.c
runtime/OpAdd.c
runtime/String.c

index b11885cad67a4a1101a7b4af32ec47e7560b1138..6107d0b7246a0eea60a3b4db82971229aa53ce4a 100644 (file)
@@ -2,3 +2,4 @@ cerise-c
 cerise-c.c
 *.o
 *.a
+tags
index bf84302b2de4b85c1418932328015c89ded0c27b..06606ef1831b0f1573ed16d238e83934385e7f5e 100755 (executable)
--- a/build.sh
+++ b/build.sh
@@ -1,10 +1,12 @@
 #!/bin/sh
 
-rm libruntime.a runtime/*.o
+OPTLEVEL=1
+
+rm -f cerise-c libruntime.a runtime/*.o
 
 for f in runtime/*.c; do
     printf "CC %s\n" "$f"
-    gcc -c -I. -O2 -o "${f%.c}.o" "$f" &
+    gcc -c -I. -O$OPTLEVEL -o "${f%.c}.o" "$f" &
 done
 wait
 printf "LIB %s\n" libruntime.a
@@ -13,4 +15,7 @@ ar rcs libruntime.a runtime/*.o
 printf "\n"
 ./cerise-c.rb > cerise-c.c \
     && gcc -I. -O2 -o cerise-c cerise-c.c libruntime.a \
+    && size cerise-c \
+    && printf "\n" \
     && ./cerise-c
+
index 9fec3feef5db3359b48209f7c443ff0d3aa23ecb..6408f0a0c90749d659884c75e9bc29ac933a26e0 100755 (executable)
@@ -465,13 +465,11 @@ class Parser
 
   def make_binop(loc, op, left, right)
     node = IR::Op.new(loc, nil, op, left, right)
-#    checker.infer(syms, node)
     node
   end
 
   def make_unop(loc, op, value)
     node = IR::Op.new(loc, nil, op, value, nil)
-#    checker.infer(syms, node)
     node
   end
 
@@ -509,20 +507,8 @@ class Parser
     key = expression()
     expect("]")
     make_binop(loc, "[", expr, key)
-
-#  def make_binop(loc, op, left, right)
-
-#    call = IR::Call.new(location, nil, expr, [])
-#    expect("(")
-#    while !matches(")")
-#      call.args << expression()
-#      expect(",") if !matches(")")
-#    end
-#    expect(")")
-#    call
   end
 
-
   def const_or_ident()
     if matches("[")
       array_literal()
@@ -1304,15 +1290,19 @@ end
 
 
 ##
-# Emit the Code
+# Parse and Analyze
 ##
 
 $parser  = Parser.new("cerise-c.m")
 $checker = TypeChecker.new($parser)
 $state = Codegen.init($parser)
 
-puts "#include <runtime.h>\n\n"
 
+##
+# Emit the Code
+##
+
+puts "#include <runtime.h>\n\n"
 $parser.syms.each do |name, val|
   args = val.value.args.map{|e| "Value #{e.name}" }.join(", ")
   puts "Value #{name}(#{args});"
index d6f9fca818f9d269f01879660e6c3dc889af1833..609f0db4dc0c84a120eaf43908da66b4197bf939 100644 (file)
--- a/runtime.h
+++ b/runtime.h
@@ -213,6 +213,7 @@ Value ToString(Value val);
  *************************************************/
 
 void Error(Value val);
+void RuntimeError(char* s);
 void Assert(char* file, int lineno, Value val);
 
 
@@ -245,3 +246,8 @@ Value Dict_Get(Value hash, Value key);
 
 Value Object_Get(Value object, Value key);
 void Object_Set(Value object, Value key, Value value);
+
+/* Garbage Collection
+ *************************************************/
+
+void* GC_Allocate(size_t nbytes);
index 442fb33476032796d2e0acd3655f87400d2694a2..c0f69977f9eced2b04dafa3357ed772ad6a65498 100644 (file)
@@ -13,10 +13,10 @@ static uint64_t NextPow2(uint64_t val) {
 }
 
 Value MakeArray(int32_t nslots) {
-    Array* array = calloc(1, sizeof(Array));
+    Array* array = GC_Allocate(sizeof(Array));
     array->length = nslots;
     array->capacity = NextPow2(nslots);
-    array->values = calloc(nslots, sizeof(Value));
+    array->values = GC_Allocate(nslots * sizeof(Value));
     return (Value){ .as_uint64 = (NAN_TAG_ARRAY | (uintptr_t)array) };
 }
 
@@ -24,7 +24,7 @@ void Array_Set(Value array, int index, Value value)
 {
     Array* ary = ValueAsArray(array);
     if (index >= ary->length) {
-        Error(MakeString("array index out of bounds"));
+        RuntimeError("array index out of bounds");
     }
     ary->values[index] = value;
 }
@@ -33,7 +33,7 @@ Value Array_Get(Value array, int index)
 {
     Array* ary = ValueAsArray(array);
     if (index >= ary->length) {
-        Error(MakeString("array index out of bounds"));
+        RuntimeError("array index out of bounds");
     }
     return ary->values[index];
 }
index d4138695adc3124d11199ffe19dbe78038583e22..0c895f82a12bec55106e587ec52a5f8217dc81a3 100644 (file)
@@ -39,7 +39,7 @@ static DictNode** FindNode(DictNode** root, DictNode* node) {
 }
 
 Value MakeDict(int32_t nslots) {
-    Dict* dict = calloc(1, sizeof(Dict));
+    Dict* dict = GC_Allocate(sizeof(Dict));
     return (Value){ .as_uint64 = (NAN_TAG_DICT | (uintptr_t)dict) };
 }
 
@@ -53,7 +53,7 @@ void Dict_Set(Value dictionary, Value key, Value value)
     Dict* dict = ValueAsDict(dictionary);
     DictNode** curr = FindNode(&(dict->root), &node);
     if (!*curr) {
-        DictNode* new_node = calloc(1, sizeof(DictNode));
+        DictNode* new_node = GC_Allocate(sizeof(DictNode));
         *new_node = node;
         *curr = new_node;
     } else {
index bb99752dd8a0cc426b3a3ade010c16644742777e..9bf98a38377f58113531c8afe480c7c4d4440d88 100644 (file)
@@ -1,6 +1,10 @@
 #include "runtime.h"
 
 void Error(Value val) {
-    fprintf(stderr, "fatal error: %s\n", ValueAsString(val)->bytes);
+    RuntimeError(ValueAsString(val)->bytes);
+}
+
+void RuntimeError(char* s) {
+    fprintf(stderr, "fatal error: %s\n", s);
     exit(1);
 }
diff --git a/runtime/GC.c b/runtime/GC.c
new file mode 100644 (file)
index 0000000..c39586c
--- /dev/null
@@ -0,0 +1,21 @@
+#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;
+}
index 153416d4d9ba07306fea3cc183a3bd3185b8c076..a85c6b1e117b722d62574baaf410ac7055cc0f1f 100644 (file)
@@ -10,7 +10,7 @@ Value Object_Get(Value object, Value key)
     } else if (IsString(object)) {
         result = String_Get(object, ValueAsInt(key));
     } else {
-        Error(MakeString("object is not indexable"));
+        RuntimeError("object is not indexable");
     }
     return result;
 }
@@ -22,6 +22,6 @@ void Object_Set(Value object, Value key, Value value)
     } else if (IsArray(object)) {
         Array_Set(object, ValueAsInt(key), value);
     } else {
-        Error(MakeString("object is not assignable"));
+        RuntimeError("object is not assignable");
     }
 }
index aa126c61fa91d4f564e17703f3247de2a54ea29d..1fd452b9155a9958ef64fc858e8331af39d60472 100644 (file)
@@ -11,7 +11,7 @@ Value OpAdd(Value left, Value right) {
         String* left_str  = ValueAsString(left);
         String* right_str = ValueAsString(right);
         size_t sz = left_str->length + right_str->length;
-        String* str = calloc(sizeof(String) + sz + 1, 1);
+        String* str = GC_Allocate(sizeof(String) + sz + 1);
         str->length = sz;
         memcpy(
             str->bytes,
@@ -23,8 +23,7 @@ Value OpAdd(Value left, Value right) {
             right_str->length + 1);
         result = (Value){ .as_uint64 = (NAN_TAG_STRING | (uint64_t)str) };
     } else {
-        fprintf(stderr, "fatal error: addition operator used on invalid type\n");
-        exit(1);
+        RuntimeError("addition operator used on invalid type");
     }
     return result;
 }
index d73c1ce9a4da20c1b81b9eb4464c9022ee515bdc..c2c2cc65c0eabb609d5961d9efdeb0d765eec405 100644 (file)
@@ -2,7 +2,7 @@
 
 Value MakeString(char* s) {
     size_t sz = strlen(s);
-    String* str = calloc(sizeof(String) + sz + 1, 1);
+    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) };
@@ -14,7 +14,7 @@ Value String_Get(Value hash, int index)
 {
     String* str = ValueAsString(hash);
     if (index >= str->length) {
-        Error(MakeString("string index out of bounds"));
+        RuntimeError("string index out of bounds");
     }
     return MakeInt( str->bytes[index] );
 }