]> git.mdlowis.com Git - proto/cerise-c.git/commitdiff
added string ops and coercion
authorMichael D. Lowis <mike@mdlowis.com>
Wed, 5 Jun 2024 02:40:10 +0000 (22:40 -0400)
committerMichael D. Lowis <mike@mdlowis.com>
Wed, 5 Jun 2024 02:40:10 +0000 (22:40 -0400)
cerise-c.m
cerise-c.rb
runtime.c
runtime.h

index 422f2a9458aed84822b8cb926573266a3b73bd55..9af7d030b314ecc89370ee764cfb48f9b1bdf539 100644 (file)
@@ -6,7 +6,6 @@ TestLiterals()
     #assert false
     #assert nil
     assert "123"
-    return true
 }
 
 TestBoolOps()
@@ -17,7 +16,6 @@ TestBoolOps()
     assert true && true
     assert true || false
     assert false || true
-    return true
 }
 
 TestIntOps()
@@ -46,8 +44,6 @@ TestIntOps()
     assert (84 / 2) == 42
     assert (21 * 2) == 42
     assert (11 % 5) == 1
-
-    return true
 }
 
 TestRealOps()
@@ -76,14 +72,28 @@ TestRealOps()
     assert (84 / 2) == 42
     assert (21 * 2) == 42
     #assert (11 % 5) == 1    # Not valid for reals
+}
 
+TestStringOps()
+{
+    assert "foo" == "foo"
+    assert "foo" != "bar"
+    assert ("foo" + "bar") == "foobar"
+    assert ("foo" + 123) == "foo123"
+    assert ("foo" + 123.0) == "foo123.000000"
+    assert ("foo" + true) == "footrue"
+    assert ("foo" + false) == "foofalse"
+#    assert length("foo") == 3
 }
 
-init()
+Main()
 {
+    def foo = 123
+    def bar = foo
     TestLiterals()
     TestBoolOps()
     TestIntOps()
     TestRealOps()
+    TestStringOps()
     return true
 }
index 2030672d0c74efa276a255c2d1656ecc48fb4f03..ac0e26004327c3525c6a202870fa36d7fc8a8c52 100755 (executable)
@@ -1147,12 +1147,11 @@ module Codegen
   end
 
   def self.emit_var(state, v)
-    pp v
     var = state.syms[v.name]
     if var.nil?
       raise "no such variable: #{v.name}"
     end
-    var
+    var.name
   end
 
   def self.emit_call(state, v)
index 8b8690294f739c428f67bd4e9e23db2b8aa57541..10e23a9bf0d06896c98816803683536bf8047cfe 100644 (file)
--- a/runtime.c
+++ b/runtime.c
@@ -109,7 +109,7 @@ int main(int argc, char** argv)
     val = ToString(MakeReal(42.5));
     assert(!strcmp(ValueAsString(val)->bytes, "42.500000"));
 
-    extern Value init(void);
-    (void)init();
+    extern Value Main(void);
+    (void)Main();
     return 0;
 }
index 33cf1b6a314befbab28e4ae77e133b7f5e129f42..1150cb44b51d764850f8c6b5100c7b0d32927836 100644 (file)
--- a/runtime.h
+++ b/runtime.h
@@ -233,6 +233,22 @@ static inline Value OpAdd(Value left, Value right) {
         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 = calloc(sizeof(String) + sz + 1, 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 {
         fprintf(stderr, "fatal error: addition operator used on invalid type\n");
         exit(1);
@@ -346,6 +362,8 @@ static inline Value OpEq(Value left, Value right) {
         result = MakeBool(ValueAsInt(left) == ValueAsInt(right));
     } else if (IsReal(left)) {
         result = MakeBool(ValueAsReal(left) == ValueAsReal(right));
+    } else if (IsString(left)) {
+        result = MakeBool(!strcmp(ValueAsString(left)->bytes, ValueAsString(right)->bytes));
     } else {
         result = MakeBool(false);
     }
@@ -360,6 +378,8 @@ static inline Value OpNeq(Value left, Value right) {
         result = MakeBool(ValueAsInt(left) != ValueAsInt(right));
     } else if (IsReal(left)) {
         result = MakeBool(ValueAsReal(left) != ValueAsReal(right));
+    } else if (IsString(left)) {
+        result = MakeBool(0 != strcmp(ValueAsString(left)->bytes, ValueAsString(right)->bytes));
     } else {
         result = MakeBool(false);
     }