aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorThomas Voss <mail@thomasvoss.com> 2024-07-09 23:04:47 +0200
committerThomas Voss <mail@thomasvoss.com> 2024-07-09 23:04:54 +0200
commit2b0228cec24e49369634cb8239a1939f0fad7e2e (patch)
tree18d6f926ae47da1485e651896bfc0a3c06d7a4c0
parent2b06086473b466fe989ce8629f941b9539ba1095 (diff)
Disallow keywords as identifier names
-rw-r--r--README8
-rw-r--r--make.c27
-rw-r--r--src/keywords.gperf40
-rw-r--r--src/parser.c6
4 files changed, 78 insertions, 3 deletions
diff --git a/README b/README
index f30fdb1..624df36 100644
--- a/README
+++ b/README
@@ -19,11 +19,15 @@ Building the Oryx compiler is rather trivial. The steps are as follows:
the version of LLVM being utilized is 17.0.6. The compiler may work
with other versions, but it isn’t guaranteed.
-2. Clone the compiler repository.
+2. Install Gperf. It should be available in your systems package
+ manager, and if not then you can easily find instructions online to
+ build from source.
+
+3. Clone the compiler repository.
$ git clone https://github.com/Mango0x45/oryx.git
-3. Bootstrap and run the build script.
+4. Bootstrap and run the build script.
$ cc -o make make.c
$ ./make # See below for more details
diff --git a/make.c b/make.c
index 5d9212b..4692189 100644
--- a/make.c
+++ b/make.c
@@ -61,7 +61,7 @@ static void mkgmp(int);
static bool tagvalid(const char *);
static void chk_cpu_flags(void);
static int globerr(const char *, int);
-static tjob cc, cc_test;
+static tjob cc, cc_test, gperf;
static void
usage(void)
@@ -158,7 +158,14 @@ main(int argc, char **argv)
glob_t g;
+ /* GNU Perf files */
+ assert(glob("src/*.gperf", 0, globerr, &g) == 0);
+ for (size_t i = 0; i < g.gl_pathc; i++)
+ tpenq(&tp, gperf, g.gl_pathv[i], NULL);
+ tpwait(&tp);
+
/* C files */
+ globfree(&g);
assert(glob("src/*.c", 0, globerr, &g) == 0);
for (size_t i = 0; i < g.gl_pathc; i++)
tpenq(&tp, cc, g.gl_pathv[i], NULL);
@@ -261,6 +268,24 @@ out:
}
void
+gperf(void *arg)
+{
+ struct strs cmd = {0};
+ char *dst = swpext(arg, "gen.c"), *src = arg;
+
+ if (!fflag && fmdnewer(dst, src))
+ goto out;
+
+ strspushl(&cmd, "gperf", src, "--output-file", dst);
+
+ cmdput(cmd);
+ cmdexec(cmd);
+ strsfree(&cmd);
+out:
+ free(dst);
+}
+
+void
ld(void)
{
glob_t g;
diff --git a/src/keywords.gperf b/src/keywords.gperf
new file mode 100644
index 0000000..7d81705
--- /dev/null
+++ b/src/keywords.gperf
@@ -0,0 +1,40 @@
+%compare-lengths
+%compare-strncmp
+%includes
+%readonly-tables
+
+%{
+#include <stdbool.h>
+
+#include "strview.h"
+
+static const char *in_word_set(const char *, size_t);
+%}
+
+%%
+pub
+static
+bool
+i8
+i16
+i32
+i64
+i128
+int
+u8
+u16
+u32
+u64
+u128
+uint
+f16
+f32
+f64
+f128
+rune
+%%
+bool
+iskeyword(strview_t sv)
+{
+ return in_word_set(sv.p, sv.len) != NULL;
+}
diff --git a/src/parser.c b/src/parser.c
index defe47d..9e748b5 100644
--- a/src/parser.c
+++ b/src/parser.c
@@ -47,6 +47,9 @@ static idx_t astalloc(ast_t *ast)
static void astresz(ast_t *ast)
__attribute__((nonnull));
+/* Generated by Gperf */
+bool iskeyword(strview_t);
+
/* TODO: Make thread-local? */
static size_t toksidx;
@@ -177,6 +180,9 @@ parsedecl(ast_t *ast, aux_t *aux, lexemes_t toks, bool toplvl)
ast->lexemes[i] = toksidx;
}
+ if (iskeyword(toks.strs[toksidx]))
+ err("parser: Cannot use reserved word as identifier");
+
if (toks.kinds[toksidx++] != LEXIDENT)
err("parser: Expected identifier");
if (toks.kinds[toksidx++] != LEXCOLON)