Use an actual string type
authorDavid Kerkeslager <kerkeslager@gmail.com>
Fri, 4 Aug 2017 14:49:20 +0000 (10:49 -0400)
committerDavid Kerkeslager <kerkeslager@gmail.com>
Fri, 4 Aug 2017 14:49:20 +0000 (10:49 -0400)
generation.py
templates/program.c

index 67c44a2..9962bf3 100644 (file)
@@ -14,7 +14,7 @@ def generate_argument(c_string_literal):
             '\\': r'\\',
         }.get(ch, ch)
 
-    return '"{}"'.format(
+    return 'stringLiteral(runtime, "{}")'.format(
         ''.join(c_escape(ch for ch in c_string_literal.value)),
     )
 
index 63b0c56..d027c52 100644 (file)
@@ -1,18 +1,96 @@
+#include <stdlib.h>
+#include <string.h>
+
 {% for standard_library in standard_libraries %}
-#include<{{standard_library}}>
+#include <{{standard_library}}>
 {% endfor %}
 
+struct String;
+typedef struct String String;
+struct Runtime;
+typedef struct Runtime Runtime;
+
+struct String
+{
+  size_t length;
+  char* characters;
+};
+
+struct Runtime
+{
+  size_t permanentStringsLength;
+  size_t permanentStringsAllocated;
+  String** permanentStrings;
+};
+
+Runtime* Runtime_construct()
+{
+  Runtime* result = malloc(sizeof(Runtime));
+  result->permanentStringsLength = 0;
+  result->permanentStringsAllocated = 0;
+  result->permanentStrings = NULL;
+  return result;
+}
+
+void Runtime_destruct(Runtime* self)
+{
+  free(self->permanentStrings);
+  free(self);
+}
+
+void Runtime_addPermanentString(Runtime* self, String* string)
+{
+  // TODO Make this function thread-safe
+  if(self->permanentStringsLength == self->permanentStringsAllocated)
+  {
+    if(self->permanentStringsAllocated == 0)
+    {
+      self->permanentStringsAllocated = 8;
+    }
+    else
+    {
+      self->permanentStringsAllocated = self->permanentStringsAllocated * 2;
+    }
+
+    self->permanentStrings = realloc(
+      self->permanentStrings,
+      sizeof(String*) * self->permanentStringsAllocated
+    );
+
+    // TODO Handle realloc returning NULL
+  }
+
+  self->permanentStrings[self->permanentStringsLength] = string;
+  self->permanentStringsLength++;
+}
+
+String* stringLiteral(Runtime* runtime, const char* literal)
+{
+  String* result = malloc(sizeof(String));
+  result->length = strlen(literal);
+  result->characters = malloc(result->length);
+  memcpy(result->characters, literal, result->length);
+  Runtime_addPermanentString(runtime, result);
+  return result;
+}
+
 {% if 'print' in builtins %}
-void builtin$print(const char* output)
+void builtin$print(String* output)
 {
-  printf("%s", output);
+  // Using fwrite instead of printf to handle size_t length
+  fwrite(output->characters, 1, output->length, stdout);
 }
 {% endif %}
 
 int main(int argc, char** argv)
 {
+  Runtime* runtime = Runtime_construct();
+
   {% for statement in statements %}
   {{ statement }}
   {% endfor %}
+
+  Runtime_destruct(runtime);
+
   return 0;
 }