summaryrefslogtreecommitdiff
path: root/igen/lexer.c
blob: 1d3268e7f60af766a59e6c326376984966d21543 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
#include <stdint.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include "lexer.h"
#include "misc.h"
#include "preprocessor.h"

cond_stmt *lex_cond_stmt(source *src, int dbg) {

}

stmt *lex_comp_stmt(source *src, int dbg) {
	char *tmp = *str;
	if (*tmp++ == '{') {
		stmt *s = lex_stmt(&tmp, dbg);
		if (*tmp++ == '}') {
			*str = tmp;
			return s;
		} else {
			throw_error(src, 1, "Missing \'}\' in compound statement.");
		}
	}
	return NULL;
}

stmt *lex_stmt(source *src, int dbg) {
	const alt_stmt alts[] = {
		{STMT_DIR, offsetof(stmt, dir), lex_dir},
		{STMT_FUNC, offsetof(stmt, func), lex_func},
		{STMT_EXPR, offsetof(stmt, expr), lex_exprs},
		{STMT_COND, offsetof(stmt, cond_stmt), lex_cond_stmt},
		{STMT_COMP, offsetof(stmt, down), lex_comp_stmt},
	};
	for (int i = 0; i < NUM_STMTS; ++i) {
		char *tmp = *str;
		void *data = alts[i].lex(&tmp, dbg);
		if (data != NULL) {
			stmt *s = calloc(1, sizeof(stmt));
			void **member = (char **)s+alts[i].offset;
			*member = data;
			return s;
		}
	}

	return NULL;
}

stmt *lex_library(source *src, stmt **end, int dbg) {
	stmt *start = lex_stmt(str, dbg);
	end = (end != NULL) ? end : &start;
	for (stmt *s = start; s != NULL; s = lex_stmt(str, dbg)) {
		(*end)->next = s;
		*end = s;
	}
	return start;
};

int lex(char *str, int dbg) {
	stmt *start = NULL;
	stmt *end = NULL;

	source *src = preprocess(str, dbg);
	start = library(&str, &end, dbg);

	return (start != NULL && end != NULL);
}