d027c52508617e57acd7313ff21f4a481a95f193
[fur] / templates / program.c
1 #include <stdlib.h>
2 #include <string.h>
3
4 {% for standard_library in standard_libraries %}
5 #include <{{standard_library}}>
6 {% endfor %}
7
8 struct String;
9 typedef struct String String;
10 struct Runtime;
11 typedef struct Runtime Runtime;
12
13 struct String
14 {
15   size_t length;
16   char* characters;
17 };
18
19 struct Runtime
20 {
21   size_t permanentStringsLength;
22   size_t permanentStringsAllocated;
23   String** permanentStrings;
24 };
25
26 Runtime* Runtime_construct()
27 {
28   Runtime* result = malloc(sizeof(Runtime));
29   result->permanentStringsLength = 0;
30   result->permanentStringsAllocated = 0;
31   result->permanentStrings = NULL;
32   return result;
33 }
34
35 void Runtime_destruct(Runtime* self)
36 {
37   free(self->permanentStrings);
38   free(self);
39 }
40
41 void Runtime_addPermanentString(Runtime* self, String* string)
42 {
43   // TODO Make this function thread-safe
44   if(self->permanentStringsLength == self->permanentStringsAllocated)
45   {
46     if(self->permanentStringsAllocated == 0)
47     {
48       self->permanentStringsAllocated = 8;
49     }
50     else
51     {
52       self->permanentStringsAllocated = self->permanentStringsAllocated * 2;
53     }
54
55     self->permanentStrings = realloc(
56       self->permanentStrings,
57       sizeof(String*) * self->permanentStringsAllocated
58     );
59
60     // TODO Handle realloc returning NULL
61   }
62
63   self->permanentStrings[self->permanentStringsLength] = string;
64   self->permanentStringsLength++;
65 }
66
67 String* stringLiteral(Runtime* runtime, const char* literal)
68 {
69   String* result = malloc(sizeof(String));
70   result->length = strlen(literal);
71   result->characters = malloc(result->length);
72   memcpy(result->characters, literal, result->length);
73   Runtime_addPermanentString(runtime, result);
74   return result;
75 }
76
77 {% if 'print' in builtins %}
78 void builtin$print(String* output)
79 {
80   // Using fwrite instead of printf to handle size_t length
81   fwrite(output->characters, 1, output->length, stdout);
82 }
83 {% endif %}
84
85 int main(int argc, char** argv)
86 {
87   Runtime* runtime = Runtime_construct();
88
89   {% for statement in statements %}
90   {{ statement }}
91   {% endfor %}
92
93   Runtime_destruct(runtime);
94
95   return 0;
96 }