* (Done) Dead code elimination - (when building conditional and loop nodes)
* (Done) Block coalescing (see above)
+ * Commutative property for constant folding
+
* https://en.wikipedia.org/wiki/Bounds-checking_elimination
* https://en.wikipedia.org/wiki/Compile-time_function_execution
* https://en.wikipedia.org/wiki/Common_subexpression_elimination
return ast_new(BEGIN, &VoidType, NULL, NULL, NULL);
}
-static void append(AstNode* node, AstNode* first, AstNode* last)
+static void append(AstNode* node, int offset, AstNode* first, AstNode* last)
{
- if (!node->links[0])
+ if (!node->links[offset + 0])
{
- node->links[0] = first;
- node->links[1] = last;
+ node->links[offset + 0] = first;
+ node->links[offset + 1] = last;
}
else
{
- node->links[1]->hdr.next = first;
- node->links[1] = last;
+ node->links[offset + 1]->hdr.next = first;
+ node->links[offset + 1] = last;
}
}
appending all its statemtents */
if (stmt->hdr.code == BEGIN)
{
- append(blk, stmt->links[0], stmt->links[1]);
+ append(blk, 0, stmt->links[0], stmt->links[1]);
}
/* otherwise just append the statement to the block */
else
{
- append(blk, stmt, stmt);
+ append(blk, 0, stmt, stmt);
}
}
void ast_call_add(AstNode* func, AstNode* arg)
{
- append(func, arg, arg);
+ append(func, 1, arg, arg);
}
AstNode* ast_if(AstNode* cond, AstNode* br1, AstNode* br2)
break;
case BEGIN:
+ printf("(begin\n");
+ for (AstNode* curr = node->links[0]; curr; curr = curr->hdr.next)
{
- printf("(begin\n");
- for (AstNode* curr = node->links[0]; curr; curr = curr->hdr.next)
- {
- print(p, curr, indent+1);
- }
- print_indent(indent, ")");
+ print(p, curr, indent+1);
}
+ print_indent(indent, ")");
break;
- case IF:
+ case CALL:
+ printf("(call\n");
+ print(p, node->links[0], indent+1);
+ for (AstNode* curr = node->links[1]; curr; curr = curr->hdr.next)
{
- printf("(if\n");
- print(p, node->links[0], indent+1);
- print(p, node->links[1], indent+1);
- if (node->links[2])
- {
- print(p, node->links[2], indent+1);
- }
- print_indent(indent, ")");
+ print(p, curr, indent+1);
}
+ print_indent(indent, ")");
break;
+ case IF:
+ printf("(if\n");
+ print(p, node->links[0], indent+1);
+ print(p, node->links[1], indent+1);
+ if (node->links[2])
+ {
+ print(p, node->links[2], indent+1);
+ }
+ print_indent(indent, ")");
+ break;
default:
if (node->links[1])
/* Item Handling
*****************************************************************************/
-Field* add_field(Parser* p, Type* type, char* name, bool export)
+static Field* add_field(Parser* p, Type* type, char* name, bool export)
{
Field* prev = NULL;
Field* curr = type->fields;
case IDENT:
expr = designator(p);
-// if (accept(p, '('))
-// {
-// Symbol* proc = symbol_get(p, item->imm.s, SYM_PROC);
-// item->type = proc->type->base;
-// Field* args = proc->type->fields;
-// Item arglist = {0};
-// Item** currarg = &(arglist.next);
-// while (args && !matches(p, ')'))
-// {
-// Item argdef = { .type = args->type };
-// Item* argval = calloc(1, sizeof(Item));
-// expression(p, argval);
-// check_types(p, &argdef, argval);
-// codegen_setarg(p, argval, (arglist.next == 0));
-// *currarg = argval;
-// currarg = &(argval->next);
-// args = args->next;
-// if (args)
-// {
-// expect(p, ',');
-// }
-// }
-// if (args)
-// {
-// error(p, "too few arguments to function '%s'", proc->name);
-// }
-// else if (!matches(p, ')'))
-// {
-// bool comma = accept(p, ',');
-// if (comma && matches(p, ')'))
-// {
-// error(p, "trailing comma in argument list");
-// }
-// else
-// {
-// error(p, "too many arguments to function '%s'", proc->name);
-// }
-// }
-// codegen_call(p, item, arglist.next);
-// expect(p, ')');
-// }
+ if (accept(p, '('))
+ {
+ expr = ast_call(expr);
+ if (expr->hdr.type->form != FORM_PROC)
+ {
+ error(p, "attempting to call a non-procedural value");
+ }
+
+ Field* args = expr->hdr.type->fields;
+ while (args && !matches(p, ')'))
+ {
+ AstNode* val = expression(p);
+ check_type(p, args->type, val);
+ ast_call_add(expr, val);
+ args = args->next;
+ if (args)
+ {
+ expect(p, ',');
+ }
+ }
+ if (args)
+ {
+ error(p, "too few arguments to function");
+ }
+ else if (!matches(p, ')'))
+ {
+ bool comma = accept(p, ',');
+ if (comma && matches(p, ')'))
+ {
+ error(p, "trailing comma in argument list");
+ }
+ else
+ {
+ error(p, "too many arguments to function");
+ }
+ }
+ expect(p, ')');
+ }
break;
default: