shithub: scc

Download patch

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;
+		}
+	}
+}