ref: eed9b5df995297c36b00d65a71e848fc4e0753ad
parent: 8dd361f8446d298a2e1d6d925da63c81143ddb4a
author: Roberto E. Vargas Caballero <[email protected]>
date: Tue Sep 19 07:12:34 EDT 2017
[as] Add skeleton for expression evaluator This skeleton is mainly taken from cc1 expression evaluator but with different precedence.
--- a/as/Makefile
+++ b/as/Makefile
@@ -4,7 +4,7 @@
include ../config.mk
include $(LIBDIR)/libdep.mk
-OBJ = main.o emit.o ins.o parser.o
+OBJ = main.o emit.o ins.o parser.o expr.o
HDR = ../inc/scc.h as.h
MOREFLAGS = $(AS_CFLAGS)
--- a/as/as.h
+++ b/as/as.h
@@ -43,6 +43,7 @@
typedef void Format(Op *, Arg *);
typedef struct section Section;
typedef struct symbol Symbol;
+typedef struct node Node;
struct line {
char *label;
@@ -88,6 +89,13 @@
struct symbol *next;
};
+struct node {
+ char op;
+ struct symbol *sym;
+ struct node *left;
+ struct node *right;
+};
+
/* emit.c */
extern char *pack(TUINT v, int n, int inc);
extern void isections(void);
@@ -106,6 +114,9 @@
#ifdef stdin
extern int nextline(FILE *fp, struct line *linep);
#endif
+
+/* expr.c */
+extern Node *expr(void);
/*
* Definition of global variables
--- /dev/null
+++ b/as/expr.c
@@ -1,0 +1,203 @@
+static char sccsid[] = "@(#) ./as/node.c";
+
+#include <string.h>
+
+#include "../inc/scc.h"
+#include "as.h"
+
+#define NNODES 10
+
+enum tokens {
+ IDEN = 1,
+ CHAR,
+ STRING,
+ SHL,
+ SHR,
+ GE,
+ LT,
+};
+
+static Alloc *arena;
+static int yytoken;
+static char *yytext;
+
+#define accept(t) (yytoken == (t) ? next() : 0)
+
+static Node *
+node(int op, Node *l, Node *r)
+{
+ struct arena *ap;
+ Node *np;
+
+ if (!arena)
+ arena = alloc(sizeof(Node), NNODES);
+ np = memset(new(arena), 0, sizeof(*np));
+ np->op = op;
+
+ return np;
+}
+
+static Node *
+binary(int op, Node *l, Node *r)
+{
+ return node(op, l, r);
+}
+
+static Node *
+unary(int op, Node *np)
+{
+ return node(op, np, NULL);
+}
+
+static int
+next(void)
+{
+ return 0;
+}
+
+static void
+unexpected(void)
+{
+ error("unexpected '%s'", yytext);
+}
+
+static void
+expect(int token)
+{
+ if (yytoken != token)
+ unexpected();
+ next();
+}
+
+/*************************************************************************/
+/* grammar functions */
+/*************************************************************************/
+
+static Node *
+primary(void)
+{
+ Node *np;
+
+ switch (yytoken) {
+ case IDEN:
+ case CHAR:
+ case STRING:
+ np = node(yytoken, NULL, NULL);
+ next();
+ break;
+ case '(':
+ next();
+ np = expr();
+ expect(')');
+ break;
+ default:
+ unexpected();
+ return NULL;
+ }
+
+ return np;
+}
+
+static Node *
+mul(void)
+{
+ int op;
+ Node *np;
+
+ np = primary();
+ for (;;) {
+ switch (op = yytoken) {
+ case '*':
+ case '/':
+ case '%':
+ case SHL:
+ case SHR:
+ next();
+ binary(op, np, primary());
+ break;
+ default: return np;
+ }
+ }
+}
+
+static Node *
+add(void)
+{
+ int op;
+ Node *np;
+
+ np = mul();
+ for (;;) {
+ switch (op = yytoken) {
+ case '+':
+ case '-':
+ next();
+ np = binary(op, np, mul());
+ break;
+ default: return np;
+ }
+ }
+}
+
+static Node *
+relational(void)
+{
+ int op;
+ Node *np;
+
+ np = add();
+ for (;;) {
+ switch (op = yytoken) {
+ case '<':
+ case '>':
+ case GE:
+ case LT:
+ next();
+ np = binary(op, np, add());
+ break;
+ default: return np;
+ }
+ }
+}
+
+static Node *
+not(void)
+{
+ Node *np;
+
+ np = relational();
+ while (accept('!'))
+ np = unary('!', relational());
+ return np;
+}
+
+static Node *
+and(void)
+{
+ int op;
+ Node *np;
+
+ np = not();
+ while (accept('&'))
+ np = binary('&', np, not());
+ return np;
+}
+
+Node *
+expr(void)
+{
+ int op;
+ Node *np;
+
+ np = and();
+ for (;;) {
+ switch (op = yytoken) {
+ case '|':
+ case '^':
+ next();
+ np = binary(op, np, and());
+ break;
+ default: return np;
+ }
+ }
+}