#include <fcntl.h>
#include <sys/stat.h>
+/* TODO
+ * Implement logical operators: and, or, not
+ * Implement arrays and array access
+ * Implement module scoped identifiers
+ * Implement strings types
+ * Implement records and record access
+ * Implement while, for, do/repeat loops
+ * Track uninitialized variables/globals
+ * Implement pointers
+ * Ownership semantics: Ownership you can count on
+ * Concurrency: Biased reference counting
+ * Nested procedure definitions
+ * Implement record extension
+ * Cleanup the lexer
+*/
+
+/* Order of Operations for Implementing Memory Management
+
+ * Implement new operator
+ * Enforce single owner pointers
+ * Implement borrowed pointers
+ * Implement biased refcounting for borrowed pointers
+
+*/
+
//#define TRACE
#ifdef TRACE
static int Indent = 0;
*****************************************************************************/
static void expression(Parser* p, Item* item);
-//RULE(param_list)
-//{
-//// (void)item;
-//// int nargs = 0;
-//// Item argdef = {0};
-//// (void)argdef;
-//// if (!matches(p, ')'))
-//// {
-//// Item arg = {0};
-//// expression(p, &arg);
-//// // if check_types()
-//// codegen_setarg(p, &arg, true);
-//// // else check_array_type()
-//// nargs++;
-////
-//// while (!matches(p, ')'))
-//// {
-//// expect(p, ',');
-//// expression(p, &arg);
-//// // if check_types()
-//// codegen_setarg(p, &arg, false);
-//// // else check_array_type()
-//// nargs++;
-//// }
-//// }
-//
-// Symbol* args = item->sym;
-//
-//}
-
RULE(qualident)
{
char* name = expect_text(p, IDENT);
item->imm.s = sym->name;
}
-
-// item->mode = sym->class;
-// item->type = sym->type;
-// item->imm = sym->imm;
-
-// if (sym->class == SYM_CONST)
-// {
-// item->mode = ITEM_CONST;
-// item->imm = sym->imm;
-// }
-
// if (accept(p, '.'))
// {
// expect(p, IDENT);
designator(p, item);
if (accept(p, '('))
{
-// codegen_prepcall(p, item);
-// param_list(p, item);
Symbol* proc = symbol_get(p, SYM_PROC, item->imm.s);
Symbol* args = proc->desc;
Item arglist = {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, ')'))
{
- error(p, "too many arguments to function '%s'", proc->name);
+ 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, ')');
}
break;
+
+ default:
+ printf("unknown factor: %d\n", peek(p)->type);
+ break;
}
}
var_decl(p, item);
}
- while (matches(p, PROCEDURE))
- {
- proc_decl(p, item);
- }
+// while (matches(p, PROCEDURE))
+// {
+// proc_decl(p, item);
+// }
/* parse the body of the procedure */
expect(p, BEGIN);
if (accept(p, RETURN))
{
expression(p, item);
+ codegen_return(p, item);
expect(p, ';');
}
+ else
+ {
+ codegen_return(p, NULL);
+ }
expect(p, END);
symbol_closescope(p);