YFLAGS+=-d --locations -v --defines=parse.h
LFLAGS+=--header-file=scan.h
-OBJECTS:=scan.o parse.o ast.o util.o
+OBJECTS:=scan.o parse.o ast.o util.o gen.o type.o
all: splc
splc: $(OBJECTS)
res->type = sassign;
res->data.sassign.ident = ident;
res->data.sassign.fields = (char **)
- list_to_array(fields, &res->data.sassign.nfield, true);
+ list_to_array(fields, &res->data.sassign.nfields, true);
res->data.sassign.expr = expr;
return res;
}
{
struct expr *res = safe_malloc(sizeof(struct expr));
res->type = estring;
- res->data.estring.nchar = 0;
+ res->data.estring.nchars = 0;
res->data.estring.chars = safe_malloc(strlen(str)+1);
char *p = res->data.estring.chars;
while(*str != '\0') {
str = unescape_char(str);
*p++ = *str++;
- res->data.estring.nchar++;
+ res->data.estring.nchars++;
}
*p = '\0';
return res;
case sassign:
pindent(indent, out);
fprintf(out, "%s", stmt->data.sassign.ident);
- for (int i = 0; i<stmt->data.sassign.nfield; i++)
+ for (int i = 0; i<stmt->data.sassign.nfields; i++)
fprintf(out, ".%s", stmt->data.sassign.fields[i]);
safe_fprintf(out, " = ");
expr_print(stmt->data.sassign.expr, out);
break;
case estring:
safe_fprintf(out, "\"");
- for (int i = 0; i<expr->data.estring.nchar; i++)
+ for (int i = 0; i<expr->data.estring.nchars; i++)
safe_fprintf(out, "%s", escape_char(
expr->data.estring.chars[i], buf, true));
safe_fprintf(out, "\"");
switch(stmt->type) {
case sassign:
free(stmt->data.sassign.ident);
- for (int i = 0; i<stmt->data.sassign.nfield; i++)
+ for (int i = 0; i<stmt->data.sassign.nfields; i++)
free(stmt->data.sassign.fields[i]);
free(stmt->data.sassign.fields);
expr_free(stmt->data.sassign.expr);
union {
struct {
char *ident;
- int nfield;
+ int nfields;
char **fields;
struct expr *expr;
} sassign;
struct expr *right;
} etuple;
struct {
- int nchar;
+ int nchars;
char *chars;
} estring;
struct {
--- /dev/null
+#include <stdbool.h>
+
+#include "ast.h"
+
+bool gen(struct ast *res)
+{
+ (void)res;
+ return true;
+}
--- /dev/null
+#ifndef GEN_H
+#define GEN_H
+
+#include <stdbool.h>
+
+#include "ast.h"
+
+bool gen(struct ast *res);
+
+#endif
#include <getopt.h>
#include "ast.h"
+#include "gen.h"
#include "parse.h"
#include "scan.h"
+#include "type.h"
extern int yylex_destroy(void);
void usage(FILE *out, char *arg0)
"Compile an spl file. If FILE is not specified stdin is used.\n"
"\n"
"Options:\n"
- "\t-p\tJust parse and pretty print\n"
- "\t-t\tJust parse and typecheck\n"
- "\t-c\tparse, typecheck and compile (default)\n"
+ "\t-p\tPretty print the parsed abstract syntax tree\n"
+ "\t-t\tPretty print the typed abstract syntax tree\n"
"\t-h\tShow this help\n"
, arg0);
}
-enum mode {parse,type,compile};
-
int main(int argc, char *argv[])
{
int opt;
- enum mode mode = compile;
+ bool pparse = false, ptype = false;
- while ((opt = getopt(argc, argv, "hptc")) != -1) {
+ while ((opt = getopt(argc, argv, "hpt")) != -1) {
switch (opt) {
case 'p':
- mode = parse;
+ pparse = true;
break;
case 't':
- mode = type;
- break;
- case 'c':
- mode = compile;
+ ptype = true;
break;
case 'h':
usage(stdout, argv[0]);
if (r != 0)
return 1;
yylex_destroy();
- if (mode == parse) {
+ if (pparse)
ast_print(result, stdout);
+ if ((result = type(result)) == NULL) {
+ r = 1;
+ goto end;
+ }
+ if (ptype)
+ ast_print(result, stdout);
+ if (!gen(result)) {
+ r = 1;
goto end;
}
-end:
ast_free(result);
+end:
if (yyin == stdin)
if (fclose(yyin) == -1)
perror("fclose");
- return 0;
+ return r;
}
--- /dev/null
+#include "ast.h"
+
+struct vardecl *type_vardecl(struct vardecl *vardecl)
+{
+ return vardecl;
+}
+
+struct decl *type_decl(struct decl *decl)
+{
+ switch (decl->type) {
+ case dfundecl:
+ fprintf(stderr, "type_decl:fundecl unsupported\n");
+ break;
+ case dvardecl:
+ decl->data.dvar = type_vardecl(decl->data.dvar);
+ break;
+ }
+ return decl;
+}
+
+struct ast *type(struct ast *ast)
+{
+ for (int i = 0; i<ast->ndecls; i++)
+ ast->decls[i] = type_decl(ast->decls[i]);
+ return ast;
+}
--- /dev/null
+#ifndef TYPE_H
+#define TYPE_H
+
+#include "ast.h"
+
+struct ast *type(struct ast *ast);
+
+#endif