CFLAGS=-Wall -W -Wno-pointer-sign -Wstrict-prototypes -Wmissing-prototypes -O2 -g
LDLIBS=-lpcre
-umpf: umpf.c cond.tab.o int.o lex.o ham.o lists.o lock.o
+umpf: umpf.c cond.tab.o lex.o ham.o lists.o lock.o code.o
gcc -o $@ $^ $(LDLIBS)
lock.o: lex.o cond.tab.o
lex.o: lex.c cond.tab.c
-int.o: int.c
-
ham.o: ham.c
+code.o: code.c
+
lists.o: lists.c
cond.tab.c: cond.y
--- /dev/null
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <ctype.h>
+
+#include "umpf.h"
+
+#define HASHSIZE 103
+#define MAGIC 19
+#define BUFSIZE 1024
+
+static struct list*
+new_var_hash(void)
+{
+ struct list* res;
+ int i;
+
+ res = xmalloc (HASHSIZE * sizeof(struct list));
+ for (i = 0; i < HASHSIZE; i++)
+ list_init(res + i);
+
+ return res;
+}
+
+static int
+get_bucket_number(char* name)
+{
+ unsigned int n = 0;
+ unsigned char* p = name;
+
+ while (*p != '\0'){
+ n = n * MAGIC + toupper(*p++);
+ }
+ n %= HASHSIZE;
+
+ return n;
+}
+
+/* if not found, variable with value "" is created */
+static int
+find_var(char* name, struct list* hash)
+{
+ int n;
+ struct variable *p;
+
+ n = get_bucket_number(name);
+ int nocase = isupper(*name);
+ LIST_FOREACH(p, hash + n)
+ if (!(nocase ? strcasecmp : strcmp)(p->name,name))
+ return p->varcode;
+
+ p = xmalloc(sizeof(struct variable));
+ p->name = xstrdup(name);
+ p->varcode = current_varcode++;
+ list_add_last(hash+n, &p->car);
+ return p->varcode;
+}
+
+void
+init(void)
+{
+ list_init(&input_code);
+ var_hash = new_var_hash();
+ const_tab = xmalloc(BUFSIZE);
+ cur_const_s = BUFSIZE;
+}
+
+static int
+store_const(char* c)
+{
+ if (cur_const_n >= cur_const_s) {
+ cur_const_s *= 2;
+ const_tab = xrealloc(const_tab, cur_const_s);
+ }
+
+ const_tab[cur_const_n] = c;
+
+ return -cur_const_n++;
+}
+
+static void
+new_instr(struct code c)
+{
+ struct code* p = xmalloc(sizeof(struct code));
+ *p = c;
+ list_add_last(&input_code, &p->car);
+}
+
+static void
+do_ass(struct tree* t)
+{
+ int var_l, var_r;
+ struct code ins;
+ var_l = find_var(t->pt.ass.left->pt.leaf.value, var_hash);
+
+ if (t->st == ST_LEAF) {
+ if (t->pt.leaf.type == L_VAR)
+ var_r = find_var(t->pt.leaf.value, var_hash);
+ else
+ var_r = store_const(t->pt.leaf.value);
+ ins.opc = SET;
+ ins.op1.i = var_l;
+ ins.op2.i = var_r;
+ new_instr(ins);
+ }
+}
+
+void
+compile(struct tree* t)
+{
+ if (!t)
+ return;
+ switch(t->st) {
+ case ST_BLOCK:
+ compile(t->pt.block.head);
+ compile(t->pt.block.tail);
+ break;
+ case ST_EMPTY:
+ break;
+ case ST_ASS:
+ do_ass(t);
+ break;
+ default:
+ die("compile: got to default");
+ }
+}
+
+void
+print_code(struct tree* t)
+{
+
+}
{
int res;
- //FIXME:
+/* //FIXME:
struct passwd* p;
p = getpwuid(getuid());
char* default_mbox = cat("/var/mail/", p->pw_name);
get_default_mailbox(default_mbox);
-
+*/
if (argc < 2)
die("Usage: ./umpf conf_file");
if (res)
return res;
-// print_tree(input_tree,0);
+ init();
+ compile(input_tree);
- var_hash = new_var_hash();
+ print_code(input_tree);
- current_headers = make_hlist();
- current_body = get_body();
+// var_hash = new_var_hash();
+// current_headers = make_hlist();
+// current_body = get_body();
// print_headers(current_headers);
-
- save_current_headers(var_hash);
- interp(input_tree, var_hash);
-
+// save_current_headers(var_hash);
+// interp(input_tree, var_hash);
// print_vars(var_hash);
return 0;
FILE* conf;
/* int.c */
-struct variable {
- struct node car;
- char* name;
- char* value;
- int modified;
-};
-
struct hlist {
struct node car;
char* name;
struct email e;
};
-struct list* var_hash;
+/* ham.c */
char* default_mailbox;
-void print_tree(struct tree* t, int ind);
-void interp(struct tree* t, struct list* hash);
-struct list* new_var_hash(void);
-void print_vars(struct list* hash);
-void save_current_headers(struct list* hash);
-
-/* ham.c */
struct list* current_headers;
struct email* current_body;
struct list* make_hlist(void);
void close_mailbox(int fd, char* path, int is_default_mailbox);
int open_mailbox(char* path, int is_default_mailbox);
char* cat(char* l, char* r);
+
+/* code.c */
+enum opcode {
+ SET,
+ JUMP,
+ JUMP_IF,
+ JUMP_UNLESS,
+ DELIVER,
+ CALL_EXT,
+ NOP
+};
+
+union op {
+ int i;
+ char* s;
+ struct code* c;
+};
+
+struct code {
+ struct node car;
+ enum opcode opc;
+ union op op1;
+ union op op2;
+ union op op3;
+};
+
+struct variable {
+ struct node car;
+ char* name;
+ int varcode;
+};
+
+struct list input_code;
+struct list* var_hash;
+int current_varcode;
+char** var_tab;
+char** const_tab;
+int cur_const_n, cur_const_s;
+
+void init(void);
+void compile(struct tree* t);
+void print_code(struct tree* t);