--- /dev/null
+expressions = (
+ greeting: 'Hello',
+ farewell: 'Goodbye',
+)
+
+print(expressions.greeting, '\n')
+print(expressions.farewell, '\n')
--- /dev/null
+Hello
+Goodbye
generate_expression(expression.right),
)
+def generate_structure_literal_expression(expression):
+ return 'Structure_construct({}, {}, {})'.format(
+ expression.field_count,
+ expression.symbol_list_variable,
+ expression.value_list_variable,
+ )
+
+def generate_dot_expression(expression):
+ return 'Structure_get(&{}, SYMBOL_LIST[{}] /* symbol: "{}" */)'.format(
+ generate_variable_expression(expression.instance),
+ expression.symbol_list_index,
+ expression.symbol,
+ )
+
def generate_list_construct_expression(expression):
return 'List_construct({})'.format(expression.allocate)
def generate_expression(expression):
return {
+ transformation.CDotExpression: generate_dot_expression,
transformation.CFunctionCallExpression: generate_function_call,
transformation.CFunctionCallForFurInfixOperator: generate_function_call_for_fur_infix_operator,
transformation.CIntegerLiteral: generate_integer_literal,
transformation.CListGetExpression: generate_list_get_expression,
transformation.CNegationExpression: generate_negation_expression,
transformation.CStringLiteral: generate_string_literal,
+ transformation.CStructureLiteralExpression: generate_structure_literal_expression,
transformation.CSymbolExpression: generate_symbol_expression,
transformation.CVariableExpression: generate_variable_expression,
}[type(expression)](expression)
', '.join(generate_expression(i) for i in statement.items),
)
+def generate_symbol_array_variable_initialization_statement(statement):
+ return 'const char* {}[] = {{ {} }};'.format(
+ statement.variable,
+ ', '.join('SYMBOL_LIST[{}] /* symbol: "{}" */'.format(
+ statement.symbol_list_indices[i],
+ statement.symbol_list[i],
+ ) for i in range(len(statement.symbol_list))),
+ )
+
def generate_variable_initialization_statement(statement):
return 'Object {} = {};'.format(
statement.variable,
transformation.CIfElseStatement: generate_if_else_statement,
transformation.CListAppendStatement: generate_list_append_statement,
transformation.CSymbolAssignmentStatement: generate_symbol_assignment_statement,
+ transformation.CSymbolArrayVariableInitializationStatement: generate_symbol_array_variable_initialization_statement,
transformation.CVariableInitializationStatement: generate_variable_initialization_statement,
transformation.CVariableReassignmentStatement: generate_variable_reassignment_statement,
}[type(statement)](statement)
],
)
+NormalDotExpression = collections.namedtuple(
+ 'NormalDotExpression',
+ [
+ 'instance',
+ 'field',
+ ],
+)
+
NormalInfixExpression = collections.namedtuple(
'NormalInfixExpression',
[
],
)
+NormalSymbolArrayVariableInitializationStatement = collections.namedtuple(
+ 'NormalSymbolArrayVariableInitializationStatement',
+ [
+ 'variable',
+ 'symbol_list',
+ ],
+)
+
NormalVariableInitializationStatement = collections.namedtuple(
'NormalVariableInitializationStatement',
[
NormalVariableExpression(variable=variable),
)
+NormalStructureLiteralExpression = collections.namedtuple(
+ 'NormalStructureLiteralExpression',
+ [
+ 'field_count',
+ 'symbol_list_variable',
+ 'value_list_variable',
+ ],
+)
+
+def normalize_structure_literal_expression(counter, expression):
+ prestatements = []
+ field_symbol_array = []
+ field_value_array = []
+
+ for symbol_expression_pair in expression.fields:
+ counter, field_prestatements, field_expression = normalize_expression(
+ counter,
+ symbol_expression_pair.expression,
+ )
+
+ for p in field_prestatements:
+ prestatements.append(p)
+
+ field_symbol_array.append(symbol_expression_pair.symbol)
+ field_value_array.append(field_expression)
+
+ symbol_array_variable = '${}'.format(counter)
+ counter += 1
+
+ prestatements.append(
+ NormalSymbolArrayVariableInitializationStatement(
+ variable=symbol_array_variable,
+ symbol_list=tuple(field_symbol_array),
+ )
+ )
+
+ value_array_variable = '${}'.format(counter)
+ counter += 1
+
+ prestatements.append(
+ NormalArrayVariableInitializationStatement(
+ variable=value_array_variable,
+ items=tuple(field_value_array),
+ )
+ )
+
+ variable = '${}'.format(counter)
+
+ prestatements.append(
+ NormalVariableInitializationStatement(
+ variable=variable,
+ expression=NormalStructureLiteralExpression(
+ field_count=len(expression.fields),
+ symbol_list_variable=symbol_array_variable,
+ value_list_variable=value_array_variable,
+ ),
+ )
+ )
+
+ return (
+ counter + 1,
+ tuple(prestatements),
+ NormalVariableExpression(variable=variable),
+ )
+
+
def normalize_symbol_expression(counter, expression):
variable = '${}'.format(counter)
return (
NormalVariableExpression(variable=result_variable),
)
+def normalize_dot_expression(counter, expression):
+ assert isinstance(expression.right, parsing.FurSymbolExpression)
+
+ counter, prestatements, left_expression = normalize_expression(counter, expression.left)
+
+ variable = '${}'.format(counter)
+
+ dot_expression_prestatement = NormalVariableInitializationStatement(
+ variable=variable,
+ expression=NormalDotExpression(
+ instance=left_expression,
+ field=expression.right.symbol,
+ ),
+ )
+
+ return (
+ counter + 1,
+ prestatements + (dot_expression_prestatement,),
+ NormalVariableExpression(variable=variable),
+ )
def normalize_infix_expression(counter, expression):
return {
'multiplication_level': normalize_basic_infix_operation,
'addition_level': normalize_basic_infix_operation,
'comparison_level': normalize_comparison_expression,
+ 'dot_level': normalize_dot_expression,
'and_level': normalize_boolean_expression,
'or_level': normalize_boolean_expression,
}[expression.order](counter, expression)
parsing.FurListItemExpression: normalize_list_item_expression,
parsing.FurNegationExpression: normalize_negation_expression,
parsing.FurStringLiteralExpression: normalize_string_literal_expression,
+ parsing.FurStructureLiteralExpression: normalize_structure_literal_expression,
parsing.FurSymbolExpression: normalize_symbol_expression,
}[type(expression)](counter, expression)
],
)
+FurSymbolExpressionPair = collections.namedtuple(
+ 'FurSymbolExpressionPair',
+ [
+ 'symbol',
+ 'expression',
+ ],
+)
+
+FurStructureLiteralExpression = collections.namedtuple(
+ 'FurStructureLiteralExpression',
+ [
+ 'fields',
+ ],
+)
+
def _integer_literal_expression_parser(index, tokens):
failure = (False, index, None)
def _parenthesized_expression_parser(index, tokens):
return _parenthese_wrapped_parser(_expression_parser)(index, tokens)
+def symbol_expression_pair_parser(index, tokens):
+ failure = (False, index, None)
+
+ if tokens[index].type == 'symbol':
+ symbol = tokens[index].match
+ index += 1
+ else:
+ return failure
+
+ if tokens[index].type == 'colon':
+ index += 1
+ else:
+ return failure
+
+ success, index, expression = _expression_parser(index, tokens)
+
+ if not success:
+ raise Exception()
+
+ return (
+ True,
+ index,
+ FurSymbolExpressionPair(
+ symbol=symbol,
+ expression=expression,
+ ),
+ )
+
+def _structure_literal_parser(index, tokens):
+ success, index, result = _parenthese_wrapped_parser(_comma_separated_list_parser(symbol_expression_pair_parser))(index, tokens)
+ return (
+ success,
+ index,
+ FurStructureLiteralExpression(
+ fields=result,
+ ),
+ )
+
def _list_literal_expression_parser(index, tokens):
failure = (False, index, None)
else:
return failure
+def _literal_level_expression_parser(index, tokens):
+ return _or_parser(
+ _list_item_expression_parser,
+ _function_call_expression_parser,
+ _parenthesized_expression_parser,
+ _integer_literal_expression_parser,
+ _string_literal_expression_parser,
+ _list_literal_expression_parser,
+ _symbol_expression_parser,
+ _structure_literal_parser,
+ )(index, tokens)
+
+def _dot_expression_parser(index, tokens):
+ return _left_recursive_infix_operator_parser(
+ lambda token: token.type == 'period',
+ _literal_level_expression_parser,
+ 'dot_level',
+ )(index, tokens)
+
def _negation_expression_parser(index, tokens):
failure = (False, index, None)
if tokens[index].match != '-':
return failure
- success, index, value = _literal_level_expression_parser(index + 1, tokens)
+ success, index, value = _dot_expression_parser(index + 1, tokens)
if not success:
return failure
return (True, index, FurNegationExpression(value=value))
-def _literal_level_expression_parser(index, tokens):
+def _negation_level_expression_parser(index, tokens):
return _or_parser(
+ _dot_expression_parser,
_negation_expression_parser,
- _list_item_expression_parser,
- _function_call_expression_parser,
- _parenthesized_expression_parser,
- _integer_literal_expression_parser,
- _string_literal_expression_parser,
- _list_literal_expression_parser,
- _symbol_expression_parser,
)(index, tokens)
def _left_recursive_infix_operator_parser(operator_token_matcher, operand_parser, order):
def _multiplication_level_expression_parser(index, tokens):
return _left_recursive_infix_operator_parser(
lambda token: token.type == 'multiplication_level_operator',
- _literal_level_expression_parser,
+ _negation_level_expression_parser,
'multiplication_level',
)(index, tokens)
),
)
-
-
-
_expression_parser = _or_parser(
_or_level_expression_parser,
_if_expression_parser, # This should always be at the top level
LIST,
STRING_CONCATENATION,
STRING_LITERAL,
+ STRUCTURE,
VOID
};
struct StringConcatenation;
typedef struct StringConcatenation StringConcatenation;
+struct Structure;
+typedef struct Structure Structure;
+struct Structure
+{
+ size_t reference_count;
+ size_t length;
+ const char** symbol_list;
+ Object* value_list;
+};
+
union Instance
{
bool boolean;
List list;
StringConcatenation* string_concatenation;
const char* string_literal;
+ Structure* structure;
};
struct Object
return list->instance.list.items[index.instance.integer];
}
+Object Object_rereference(Object self)
+{
+ switch(self.type)
+ {
+ case BOOLEAN:
+ case CLOSURE:
+ case INTEGER:
+ case STRING_LITERAL:
+ case VOID:
+ return self;
+
+ case STRING_CONCATENATION:
+ self.instance.string_concatenation->referenceCount++;
+ return self;
+
+ case STRUCTURE:
+ self.instance.structure->reference_count++;
+ return self;
+
+ default:
+ assert(false);
+ }
+}
+
+Object Structure_construct(size_t length, const char** symbol_list, Object* value_list)
+{
+ Structure* structure = malloc(sizeof(Structure));
+ structure->reference_count = 1;
+ structure->length = length;
+ structure->symbol_list = malloc(sizeof(const char*) * length);
+ structure->value_list = malloc(sizeof(Object) * length);
+
+ // TODO Don't allow assignment of mutable structures, as this screws up reference counting
+ for(size_t i = 0; i < length; i++)
+ {
+ structure->symbol_list[i] = symbol_list[i];
+ structure->value_list[i] = Object_rereference(value_list[i]);
+ }
+
+ Object result = { STRUCTURE, (Instance)structure };
+
+ return result;
+}
+
+Object Structure_get(Object* self, const char* symbol)
+{
+ assert(self->type == STRUCTURE);
+
+ for(size_t i = 0; i < self->instance.structure->length; i++)
+ {
+ if(self->instance.structure->symbol_list[i] == symbol)
+ {
+ return self->instance.structure->value_list[i];
+ }
+ }
+
+ assert(false);
+}
+
struct EnvironmentNode
{
const char* key;
}
break;
+ case STRUCTURE:
+ self->instance.structure->reference_count--;
+
+ if(self->instance.structure->reference_count == 0)
+ {
+ for(size_t i = 0; i < self->instance.structure->length; i++)
+ {
+ Object_deinitialize(&(self->instance.structure->value_list[i]));
+ }
+ free(self->instance.structure->symbol_list);
+ free(self->instance.structure->value_list);
+ free(self->instance.structure);
+ }
+ break;
+
default:
assert(false);
}
{
switch(left.type) {
case STRING_CONCATENATION:
- left.instance.string_concatenation->referenceCount++;
- break;
-
case STRING_LITERAL:
break;
switch(right.type) {
case STRING_CONCATENATION:
- right.instance.string_concatenation->referenceCount++;
- break;
-
case STRING_LITERAL:
break;
StringConcatenation* concatenation = malloc(sizeof(StringConcatenation));
concatenation->referenceCount = 1;
- concatenation->left = left;
- concatenation->right = right;
+ concatenation->left = Object_rereference(left);
+ concatenation->right = Object_rereference(right);
Object result = { STRING_CONCATENATION, (Instance)concatenation };
return result;
('open_parenthese', r'\('),
('close_parenthese', r'\)'),
('comma', r','),
+ ('colon', r':'),
+ ('period', r'\.'),
('integer_literal', r'\d+'),
('symbol', r'[a-z_]+'),
('single_quoted_string_literal', r"'.*?'"),
],
)
+CStructureLiteralExpression = collections.namedtuple(
+ 'CStructureLiteralExpression',
+ [
+ 'field_count',
+ 'symbol_list_variable',
+ 'value_list_variable',
+ ],
+)
+
+CDotExpression = collections.namedtuple(
+ 'CDotExpression',
+ [
+ 'instance',
+ 'symbol',
+ 'symbol_list_index',
+ ],
+)
+
CNegationExpression = collections.namedtuple(
'CNegationExpression',
[
],
)
+CSymbolArrayVariableInitializationStatement = collections.namedtuple(
+ 'CSymbolArrayVariableInitializationStatement',
+ [
+ 'variable',
+ 'symbol_list',
+ 'symbol_list_indices',
+ ],
+)
+
CVariableInitializationStatement = collections.namedtuple(
'CVariableInitializationStatement',
[
}
def transform_variable_expression(accumulators, expression):
+ assert isinstance(expression, normalization.NormalVariableExpression)
return CVariableExpression(variable=expression.variable)
def transform_string_literal_expression(accumulators, expression):
],
)
+def transform_structure_literal_expression(accumulators, expression):
+ return CStructureLiteralExpression(
+ field_count=expression.field_count,
+ symbol_list_variable=expression.symbol_list_variable,
+ value_list_variable=expression.value_list_variable,
+ )
+
+def transform_dot_expression(accumulators, expression):
+ try:
+ symbol_list_index = accumulators.symbol_list.index(expression.field)
+
+ except ValueError:
+ symbol_list_index = len(accumulators.symbol_list)
+ accumulators.symbol_list.append(expression.field)
+
+ return CDotExpression(
+ instance=transform_variable_expression(accumulators, expression.instance),
+ symbol=expression.field,
+ symbol_list_index=symbol_list_index,
+ )
+
def transform_list_construct_expression(accumulators, expression):
return CListConstructExpression(allocate=expression.allocate)
parsing.FurIntegerLiteralExpression: transform_integer_literal_expression,
parsing.FurNegationExpression: transform_negation_expression,
parsing.FurStringLiteralExpression: transform_string_literal_expression,
+ normalization.NormalDotExpression: transform_dot_expression,
normalization.NormalFunctionCallExpression: transform_function_call_expression,
normalization.NormalInfixExpression: transform_infix_expression,
normalization.NormalIntegerLiteralExpression: transform_integer_literal_expression,
normalization.NormalListConstructExpression: transform_list_construct_expression,
normalization.NormalListGetExpression: transform_list_get_expression,
normalization.NormalNegationExpression: transform_negation_expression,
+ normalization.NormalStructureLiteralExpression: transform_structure_literal_expression,
normalization.NormalStringLiteralExpression: transform_string_literal_expression,
normalization.NormalSymbolExpression: transform_symbol_expression,
normalization.NormalVariableExpression: transform_variable_expression,
items=tuple(transform_expression(accumulators, i) for i in statement.items),
)
+def transform_symbol_array_variable_initialization_statement(accumulators, statement):
+ symbol_list_indices = []
+
+ for symbol in statement.symbol_list:
+ try:
+ symbol_list_index = accumulators.symbol_list.index(symbol)
+ except ValueError:
+ symbol_list_index = len(accumulators.symbol_list)
+ accumulators.symbol_list.append(symbol)
+
+ symbol_list_indices.append(symbol_list_index)
+
+ return CSymbolArrayVariableInitializationStatement(
+ variable=statement.variable,
+ symbol_list=statement.symbol_list,
+ symbol_list_indices=tuple(symbol_list_indices),
+ )
+
def transform_variable_initialization_statement(accumulators, statement):
return CVariableInitializationStatement(
variable=statement.variable,
normalization.NormalFunctionDefinitionStatement: transform_function_definition_statement,
normalization.NormalIfElseStatement: transform_if_else_statement,
normalization.NormalListAppendStatement: transform_list_append_statement,
+ normalization.NormalSymbolArrayVariableInitializationStatement: transform_symbol_array_variable_initialization_statement,
normalization.NormalVariableInitializationStatement: transform_variable_initialization_statement,
normalization.NormalVariableReassignmentStatement: transform_variable_reassignment_statement,
}[type(statement)](accumulators, statement)