def generate_argument(instruction):
try:
return {
+ 'add': generate_size_t_argument,
'drop': generate_null_argument,
'end': generate_null_argument,
'call': generate_size_t_argument,
+ 'idiv': generate_size_t_argument,
+ 'mod': generate_size_t_argument,
+ 'mul': generate_size_t_argument,
+ 'pop': generate_symbol_argument,
'push': generate_symbol_argument,
'push_integer': generate_integer_argument,
'push_string': generate_string_argument,
+ 'sub': generate_size_t_argument,
}[instruction.instruction](instruction.argument)
except KeyError:
import normalization
+CPSBuiltinExpression = collections.namedtuple(
+ 'CPSBuiltinExpression',
+ (
+ 'symbol',
+ ),
+)
+
CPSFunctionCallExpression = collections.namedtuple(
'CPSFunctionCallExpression',
(
),
)
+def convert_builtin_expression(expression):
+ return CPSBuiltinExpression(symbol=expression.symbol)
+
def convert_function_call_expression(expression):
return CPSFunctionCallExpression(
metadata=expression.metadata,
def convert_expression(expression):
return {
+ normalization.NormalBuiltinExpression: convert_builtin_expression,
normalization.NormalFunctionCallExpression: convert_function_call_expression,
normalization.NormalIfElseExpression: convert_if_else_expression,
normalization.NormalIntegerLiteralExpression: convert_integer_literal_expression,
def generate_symbol_literal(symbol):
return 'sym({})'.format(symbol)
+def generate_instruction_name_from_builtin(builtin):
+ try:
+ return {
+ '__add__': 'add',
+ '__subtract__': 'sub',
+ '__multiply__': 'mul',
+ '__integer_divide__': 'idiv',
+ '__modular_divide__': 'mod',
+ }[builtin]
+
+ except KeyError:
+ import ipdb; ipdb.set_trace()
+
def generate_function_call_expression(counters, expression):
+ if isinstance(expression.function_expression, conversion.CPSBuiltinExpression):
+ return (
+ (),
+ (
+ CIRInstruction(
+ instruction=generate_instruction_name_from_builtin(
+ expression.function_expression.symbol,
+ ),
+ argument=expression.argument_count,
+ ),
+ )
+ )
+
referenced_entry_list, instruction_list = generate_expression(
counters,
expression.function_expression,
import parsing
+DesugaredBuiltinExpression = collections.namedtuple(
+ 'DesugaredBuiltinExpression',
+ (
+ 'metadata',
+ 'symbol',
+ ),
+)
+
DesugaredFunctionCallExpression = collections.namedtuple(
'DesugaredFunctionCallExpression',
(
return DesugaredFunctionCallExpression(
metadata=expression.metadata,
- function=DesugaredSymbolExpression(
+ function=DesugaredBuiltinExpression(
metadata=expression.metadata,
symbol=function,
),
def desugar_list_item_expression(expression):
return DesugaredFunctionCallExpression(
metadata=expression.metadata,
- function=DesugaredSymbolExpression(
+ function=DesugaredBuiltinExpression(
metadata=expression.metadata,
symbol='__get__',
),
def desugar_negation_expression(expression):
return DesugaredFunctionCallExpression(
metadata=expression.metadata,
- function=DesugaredSymbolExpression(
+ function=DesugaredBuiltinExpression(
metadata=expression.metadata,
symbol='__negate__',
),
import desugaring
import util
+NormalBuiltinExpression = collections.namedtuple(
+ 'NormalBuiltinExpression',
+ (
+ 'symbol',
+ ),
+)
+
NormalVariableExpression = collections.namedtuple(
'NormalVariableExpression',
[
],
)
+def normalize_builtin_expression(counter, expression):
+ return (
+ counter,
+ (),
+ NormalBuiltinExpression(symbol=expression.symbol),
+ )
+
def normalize_integer_literal_expression(counter, expression):
return (
counter,
for ps in function_prestatements:
prestatements.append(ps)
- result_variable = '${}'.format(counter)
-
- prestatements.append(
- NormalVariableInitializationStatement(
- variable=result_variable,
- expression=NormalFunctionCallExpression(
- metadata=expression.metadata,
- function_expression=function_expression,
- argument_count=len(expression.argument_list),
- ),
- )
- )
-
return (
- counter + 1,
+ counter,
tuple(prestatements),
- NormalVariableExpression(variable=result_variable),
+ NormalFunctionCallExpression(
+ metadata=expression.metadata,
+ function_expression=function_expression,
+ argument_count=len(expression.argument_list),
+ ),
)
def normalize_if_expression(counter, expression):
def normalize_expression(counter, expression):
return {
+ desugaring.DesugaredBuiltinExpression: normalize_builtin_expression,
desugaring.DesugaredFunctionCallExpression: normalize_function_call_expression,
desugaring.DesugaredIfExpression: normalize_if_expression,
desugaring.DesugaredIntegerLiteralExpression: normalize_integer_literal_expression,
--- /dev/null
+void {{ name }}(struct Thread* thread, const union Argument argument) {
+ // We're going to reuse result as both the addend and the sum
+ assert(!Stack_isEmpty(&(thread->stack)));
+ Object result = Stack_pop(&(thread->stack));
+ assert(result.type == INTEGER);
+
+ assert(!Stack_isEmpty(&(thread->stack)));
+ Object other = Stack_pop(&(thread->stack));
+ assert(result.type == INTEGER);
+
+ result.value.integer = other.value.integer {{ operation }} result.value.integer;
+
+ Stack_push(&(thread->stack), result);
+}
--- /dev/null
+struct _EnvironmentNode;
+typedef struct _EnvironmentNode _EnvironmentNode;
+struct _EnvironmentNode {
+ const char* symbol;
+ Object value;
+ _EnvironmentNode* next;
+};
+
+struct Environment;
+typedef struct Environment Environment;
+struct Environment {
+ _EnvironmentNode* top;
+};
+
+struct Environment_get_Result;
+typedef struct Environment_get_Result Environment_get_Result;
+struct Environment_get_Result {
+ bool found;
+ Object result;
+};
+
+void Environment_initialize(Environment* self) {
+ self->top = NULL;
+}
+
+void Environment_deinitialize(Environment* self) {
+ while(self->top != NULL) {
+ _EnvironmentNode* en = self->top;
+ self->top = en->next;
+ Object_deinitialize(&(en->value));
+ free(en);
+ }
+}
+
+Environment* Environment_construct() {
+ Environment* result = malloc(sizeof(Environment));
+ Environment_initialize(result);
+ return result;
+}
+
+void Environment_destruct(Environment* self) {
+ Environment_deinitialize(self);
+ free(self);
+}
+
+Environment_get_Result Environment_get(Environment* self, char* symbol) {
+ for(_EnvironmentNode* current = self->top; current != NULL; current = current->next) {
+ if(strcmp(current->symbol, symbol) == 0) {
+ return (Environment_get_Result) { true, current->value };
+ }
+ }
+ return (Environment_get_Result) { false, BUILTIN_NIL };
+}
+
+void Environment_set(Environment* self, char* symbol, Object value) {
+ assert(!(Environment_get(self, symbol).found));
+
+ _EnvironmentNode* en = malloc(sizeof(_EnvironmentNode));
+ en->symbol = symbol;
+ en->value = value;
+ en->next = self->top;
+ self->top = en;
+}
void Object_deinitialize(Object* self) {
}
+{% include "environment.c" %}
{% include "stack.c" %}
struct Thread;
typedef struct Thread Thread;
struct Thread {
+ Environment* environment;
Stack stack;
size_t program_counter;
};
void Thread_initialize(Thread* self, size_t program_counter) {
+ self->environment = Environment_construct();
Stack_initialize(&(self->stack));
self->program_counter = program_counter;
}
void Thread_deinitialize(Thread* self) {
+ Environment_destruct(self->environment);
Stack_deinitialize(&(self->stack));
}
}
}
+{% with name='add', operation='+' %}
+ {% include "arithmetic_instruction.c" %}
+{% endwith %}
+
+
void drop(struct Thread* thread, const union Argument argument) {
assert(!Stack_isEmpty(&(thread->stack)));
Object result = Stack_pop(&(thread->stack));
void end(struct Thread* thread, const union Argument argument) {
}
-void push(struct Thread* thread, const union Argument argument) {
+{% with name='idiv', operation='/' %}
+ {% include "arithmetic_instruction.c" %}
+{% endwith %}
+
+{% with name='mod', operation='%' %}
+ {% include "arithmetic_instruction.c" %}
+{% endwith %}
+
+{% with name='mul', operation='*' %}
+ {% include "arithmetic_instruction.c" %}
+{% endwith %}
+
+void pop(struct Thread* thread, const union Argument argument) {
char* argumentString = argument.string;
- Object result;
+ assert(!Stack_isEmpty(&(thread->stack)));
+ Object result = Stack_pop(&(thread->stack));
if(strcmp(argumentString, "print") == 0) {
+ assert(false);
+ }
+
+ Environment_set(thread->environment, argumentString, result);
+}
+
+void push(struct Thread* thread, const union Argument argument) {
+ char* argumentString = argument.string;
+
+ if(strcmp(argumentString, "print") == 0) {
+ Object result;
result.type = BUILTIN;
result.value.builtin = PRINT;
+ Stack_push(&(thread->stack), result);
} else {
- assert(false);
+ Environment_get_Result result = Environment_get(thread->environment, argumentString);
+ if(!result.found) {
+ fprintf(stderr, "Variable `%s` not found", argumentString);
+ assert(false);
+ }
+ Stack_push(&(thread->stack), result.result);
}
-
- Stack_push(&(thread->stack), result);
}
void push_integer(struct Thread* thread, const union Argument argument) {
Stack_push(&(thread->stack), result);
}
+{% with name='sub', operation='-' %}
+ {% include "arithmetic_instruction.c" %}
+{% endwith %}
+
struct Instruction;
typedef const struct Instruction Instruction;
struct Instruction {
-struct StackNode;
-typedef struct StackNode StackNode;
-struct StackNode {
+struct _StackNode;
+typedef struct _StackNode _StackNode;
+struct _StackNode {
Object value;
- StackNode* next;
+ _StackNode* next;
};
struct Stack;
typedef struct Stack Stack;
struct Stack {
- StackNode* top;
+ _StackNode* top;
};
void Stack_initialize(Stack* self) {
}
void Stack_push(Stack* self, Object value) {
- StackNode* node = malloc(sizeof(StackNode));
+ _StackNode* node = malloc(sizeof(_StackNode));
node->value = value;
node->next = self->top;
self->top = node;
Object Stack_pop(Stack* self) {
assert(self->top != NULL);
- StackNode* node = self->top;
+ _StackNode* node = self->top;
self->top = node->next;
Object result = node->value;