# TODO Check the type of the things being called
function_expression = generate_variable_expression(function_call.function_expression)
- return '{}.instance.closure.call(environmentPool, {}.instance.closure.closed, {}, {})'.format(
+ return '{}.instance.closure.call(environmentPool, {}.instance.closure.closed, {}, stack)'.format(
function_expression,
function_expression,
function_call.argument_count,
- # TODO This is just a single item containing a reference to the items list--make that clearer
- generate_expression(function_call.argument_items),
)
def generate_expression_statement(statement):
generate_expression(statement.item_expression),
)
+def generate_push_statement(statement):
+ return 'Stack_push(stack, {});'.format(generate_expression(statement.expression))
+
def generate_statement(statement):
return {
transformation.CArrayVariableInitializationStatement: generate_array_variable_initialization_statement,
transformation.CFunctionDeclaration: generate_function_declaration,
transformation.CIfElseStatement: generate_if_else_statement,
transformation.CListAppendStatement: generate_list_append_statement,
+ transformation.CPushStatement: generate_push_statement,
transformation.CSymbolAssignmentStatement: generate_symbol_assignment_statement,
transformation.CSymbolArrayVariableInitializationStatement: generate_symbol_array_variable_initialization_statement,
transformation.CVariableInitializationStatement: generate_variable_initialization_statement,
],
)
+NormalPushStatement = collections.namedtuple(
+ 'NormalPushStatement',
+ (
+ 'expression',
+ ),
+)
+
NormalFunctionCallExpression = collections.namedtuple(
'NormalFunctionCallExpression',
[
'function_expression',
'argument_count',
- 'argument_items',
],
)
assert isinstance(expression, parsing.FurFunctionCallExpression)
prestatements = []
- arguments = []
for argument in expression.arguments:
counter, argument_prestatements, normalized_argument = normalize_expression(counter, argument)
expression=normalized_argument,
)
)
- arguments.append(NormalVariableExpression(
- variable=variable,
- ))
+ prestatements.append(
+ NormalPushStatement(
+ expression=NormalVariableExpression(
+ variable=variable,
+ ),
+ ),
+ )
counter += 1
- arguments_variable = '${}'.format(counter)
- counter += 1
-
- prestatements.append(NormalArrayVariableInitializationStatement(
- variable=arguments_variable,
- items=tuple(arguments),
- ))
-
counter, function_prestatements, function_expression = normalize_expression(
counter,
expression.function,
variable=result_variable,
expression=NormalFunctionCallExpression(
function_expression=function_expression,
- argument_count=len(arguments),
- argument_items=NormalVariableExpression(variable=arguments_variable),
+ argument_count=len(expression.arguments),
),
)
)
-Object user${{name}}$implementation(EnvironmentPool* environmentPool, Environment* parent, size_t argc, Object* args)
+Object user${{name}}$implementation(EnvironmentPool* environmentPool, Environment* parent, size_t argc, Stack* stack)
{
- assert(argc == {{ argument_name_list|length }});
-
Environment* environment = EnvironmentPool_allocate(environmentPool);
Environment_initialize(environment, parent);
Object result = builtin$nil;
- {% for argument_name in argument_name_list %}
- Environment_set(environment, "{{ argument_name }}", args[{{ loop.index0 }}]);
+ {% for argument_name in argument_name_list|reverse %}
+ Environment_set(environment, "{{ argument_name }}", Stack_pop(stack));
{% endfor %}
{% for statement in statement_list %}
typedef struct Environment Environment;
struct EnvironmentPool;
typedef struct EnvironmentPool EnvironmentPool;
+struct Stack;
+typedef struct Stack Stack;
const char* const STRING_LITERAL_LIST[] = {
{% for string_literal in string_literal_list %}
struct Closure
{
Environment* closed;
- Object (*call)(EnvironmentPool*, Environment*, size_t, Object*);
+ Object (*call)(EnvironmentPool*, Environment*, size_t, Stack*);
};
struct List;
return list->instance.list.items[index.instance.integer];
}
+struct Stack
+{
+ uint16_t length;
+ Object items[256];
+};
+
+void Stack_initialize(Stack* self)
+{
+ self->length = 0;
+}
+
+void Stack_push(Stack* self, Object item)
+{
+ assert(self->length < 256);
+ self->items[self->length] = item;
+ self->length++;
+}
+
+Object Stack_pop(Stack* self)
+{
+ assert(self->length > 0);
+ self->length--;
+ return self->items[self->length];
+}
+
Object Object_rereference(Object self)
{
switch(self.type)
{% endfor %}
{% if 'pow' in builtins %}
-Object builtin$pow$implementation(EnvironmentPool* environmentPool, Environment* parent, size_t argc, Object* args)
+Object builtin$pow$implementation(EnvironmentPool* environmentPool, Environment* parent, size_t argc, Stack* stack)
{
- assert(argc == 2);
-
- Object base = args[0];
- Object exponent = args[1];
+ // Must unload items in reverse order
+ Object exponent = Stack_pop(stack);
+ Object base = Stack_pop(stack);
assert(base.type == INTEGER);
assert(exponent.type == INTEGER);
{% endif %}
{% if 'print' in builtins %}
-Object builtin$print$implementation(EnvironmentPool* environmentPool, Environment* parent, size_t argc, Object* args)
+Object builtin$print$implementation(EnvironmentPool* environmentPool, Environment* parent, size_t argc, Stack* stack)
{
+ Stack reverse_stack;
+ Stack_initialize(&reverse_stack);
+
for(size_t i = 0; i < argc; i++)
{
- Object output = args[i];
+ Stack_push(&reverse_stack, Stack_pop(stack));
+ }
+
+ while(reverse_stack.length > 0)
+ {
+ Object output = Stack_pop(&reverse_stack);
switch(output.type)
{
case BOOLEAN:
break;
case STRING_CONCATENATION:
- builtin$print$implementation(NULL, NULL, 1, &(output.instance.string_concatenation->left));
- builtin$print$implementation(NULL, NULL, 1, &(output.instance.string_concatenation->right));
+ Stack_push(stack, output.instance.string_concatenation->left);
+ builtin$print$implementation(NULL, NULL, 1, stack);
+ Stack_push(stack, output.instance.string_concatenation->right);
+ builtin$print$implementation(NULL, NULL, 1, stack);
break;
case STRING_LITERAL:
Environment* environment = EnvironmentPool_allocate(environmentPool);
Environment_initialize(environment, NULL);
+ Stack stackMemory;
+ Stack* stack = &stackMemory;
+ Stack_initialize(stack);
+
// TODO Use the symbol from SYMBOL_LIST
{% for builtin in builtins %}
Environment_set(environment, "{{ builtin }}", builtin${{ builtin }});
],
)
+CPushStatement = collections.namedtuple(
+ 'CPushStatement',
+ (
+ 'expression',
+ ),
+)
+
CFunctionCallExpression = collections.namedtuple(
'CFunctionCallExpression',
[
'function_expression',
'argument_count',
- 'argument_items',
],
)
return CFunctionCallExpression(
function_expression=transform_expression(accumulators, function_call.function_expression),
argument_count=function_call.argument_count,
- argument_items=transform_expression(accumulators, function_call.argument_items),
)
def transform_expression_statement(accumulators, statement):
return CFunctionDeclaration(name=statement.name)
+def transform_push_statement(accumulators, statement):
+ return CPushStatement(expression=transform_expression(accumulators, statement.expression))
+
def transform_statement(accumulators, statement):
return {
parsing.FurExpressionStatement: transform_expression_statement,
normalization.NormalFunctionDefinitionStatement: transform_function_definition_statement,
normalization.NormalIfElseStatement: transform_if_else_statement,
normalization.NormalListAppendStatement: transform_list_append_statement,
+ normalization.NormalPushStatement: transform_push_statement,
normalization.NormalSymbolArrayVariableInitializationStatement: transform_symbol_array_variable_initialization_statement,
normalization.NormalVariableInitializationStatement: transform_variable_initialization_statement,
normalization.NormalVariableReassignmentStatement: transform_variable_reassignment_statement,