--- /dev/null
+42
\ No newline at end of file
import jinja2
+import transformation
+
ENV = jinja2.Environment(
autoescape=jinja2.select_autoescape([]),
loader=jinja2.FileSystemLoader('templates'),
trim_blocks=True,
)
-def generate_argument(c_string_literal):
+def generate_integer_literal(c_integer_literal):
+ return 'integerLiteral({})'.format(c_integer_literal.value)
+
+def generate_string_literal(c_string_literal):
def c_escape(ch):
return {
'\n': r'\n',
''.join(c_escape(ch for ch in c_string_literal.value)),
)
+def generate_argument(c_argument):
+ return {
+ transformation.CIntegerLiteral: generate_integer_literal,
+ transformation.CStringLiteral: generate_string_literal,
+ }[type(c_argument)](c_argument)
+
def generate_statement(c_function_call_statement):
return '{}({});'.format(
c_function_call_statement.name,
import collections
+IntegerLiteral = collections.namedtuple(
+ 'IntegerLiteral',
+ [
+ 'value',
+ ],
+)
+
StringLiteral = collections.namedtuple(
'StringLiteral',
[
],
)
+def _integer_literal_parser(index, tokens):
+ failure = (False, index, None)
+
+ if tokens[index].type != 'integer_literal':
+ return failure
+ value = int(tokens[index].match)
+ index += 1
+
+ return True, index, IntegerLiteral(value=value)
+
def _string_literal_parser(index, tokens):
failure = (False, index, None)
return True, index, StringLiteral(value=value)
+def _argument_parser(index, tokens):
+ failure = (False, index, None)
+
+ for parser in [_integer_literal_parser, _string_literal_parser]:
+ success, index, value = parser(index, tokens)
+
+ if success:
+ return (success, index, value)
+
+ return failure
+
FunctionCall = collections.namedtuple(
'FunctionCall',
return failure
index += 1
- success, index, argument = _string_literal_parser(index, tokens)
+ success, index, argument = _argument_parser(index, tokens)
if not success:
return failure
+#include <assert.h>
+#include <inttypes.h>
+#include <stdbool.h>
#include <stdlib.h>
#include <string.h>
struct String;
typedef struct String String;
+enum Type;
+typedef enum Type Type;
+union Instance;
+typedef union Instance Instance;
+struct Object;
+typedef struct Object Object;
struct Runtime;
typedef struct Runtime Runtime;
char* characters;
};
+enum Type
+{
+ INTEGER,
+ STRING
+};
+
+union Instance
+{
+ int32_t integer;
+ String* string;
+};
+
+struct Object
+{
+ Type type;
+ Instance instance;
+};
+
struct Runtime
{
size_t permanentStringsLength;
self->permanentStringsLength++;
}
-String* stringLiteral(Runtime* runtime, const char* literal)
+Object integerLiteral(int32_t 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);
+ Object result;
+ result.type = INTEGER;
+ result.instance.integer = literal;
+ return result;
+}
+
+Object stringLiteral(Runtime* runtime, const char* literal)
+{
+ String* resultString = malloc(sizeof(String));
+ resultString->length = strlen(literal);
+ resultString->characters = malloc(resultString->length);
+ memcpy(resultString->characters, literal, resultString->length);
+ Runtime_addPermanentString(runtime, resultString);
+
+ Object result;
+ result.type = STRING;
+ result.instance.string = resultString;
return result;
}
{% if 'print' in builtins %}
-void builtin$print(String* output)
+void builtin$print(Object output)
{
- // Using fwrite instead of printf to handle size_t length
- fwrite(output->characters, 1, output->length, stdout);
+ switch(output.type)
+ {
+ case INTEGER:
+ printf("%" PRId32, output.instance.integer);
+ break;
+
+ case STRING:
+ // Using fwrite instead of printf to handle size_t length
+ fwrite(output.instance.string->characters, 1, output.instance.string->length, stdout);
+ break;
+
+ default:
+ assert(false);
+ }
}
{% endif %}
_TOKEN_MATCHERS = [
('open_parenthese', r'\('),
('close_parenthese', r'\)'),
+ ('integer_literal', r'-?\s*\d+'),
('symbol', r'[a-z]+'),
('single_quoted_string_literal', r"'.*?'"),
]
import parsing
+CIntegerLiteral = collections.namedtuple(
+ 'CIntegerLiteral',
+ [
+ 'value',
+ ],
+)
+
CStringLiteral = collections.namedtuple(
'CStringLiteral',
[
}
def transform_argument(builtin_dependencies, argument):
- if isinstance(argument, parsing.StringLiteral):
- return CStringLiteral(value=argument.value)
-
- raise Exception()
+ return {
+ parsing.IntegerLiteral: CIntegerLiteral,
+ parsing.StringLiteral: CStringLiteral,
+ }[type(argument)](value=argument.value)
def transform_function_call_statement(builtin_dependencies, function_call):
if function_call.name in BUILTINS.keys():