Implemented start of flagpole compiler and a few new things here and there for said compiler
This commit is contained in:
parent
0e1237f0be
commit
6098f88cc5
8 changed files with 401 additions and 2 deletions
63
flagpole/bldit.lua
Normal file
63
flagpole/bldit.lua
Normal file
|
|
@ -0,0 +1,63 @@
|
|||
bldit_version = "1.1.3"
|
||||
package_version = "1.1.3"
|
||||
|
||||
dependencies = {}
|
||||
|
||||
exec_name = "fvmfpc"
|
||||
libs = "-Wall -Wextra"
|
||||
includes = "-I../Lazyc"
|
||||
|
||||
execute = function(str)
|
||||
print(str)
|
||||
return os.execute(str)
|
||||
end
|
||||
|
||||
targets = {
|
||||
default = {
|
||||
build = function()
|
||||
e,h,c = execute("rm -fr build")
|
||||
if c ~= 0 and c ~= nil then
|
||||
print("Build Error")
|
||||
print("GIVEN UP")
|
||||
return c
|
||||
end
|
||||
e,h,c = execute("mkdir build")
|
||||
if c ~= 0 and c ~= nil then
|
||||
print("Build Error")
|
||||
print("GIVEN UP")
|
||||
return c
|
||||
end
|
||||
cmd = [[find src -type f -name "*.c" -print]]
|
||||
p = io.popen(cmd)
|
||||
assert(p, "File detection error, GIVEN UP")
|
||||
|
||||
for f in p:lines() do
|
||||
base = f:match("([^/]+)%.c$")
|
||||
obj = "build/"..base..".o"
|
||||
cc = "cc -c '"..f.."' -o '"..obj.."' "..includes
|
||||
e,h,c = execute(cc)
|
||||
if c ~= 0 and c ~= nil then
|
||||
print("Compilation Error")
|
||||
print("GIVEN UP")
|
||||
return c
|
||||
end
|
||||
end
|
||||
p:close()
|
||||
e,h,c = execute("cc build/*.o "..libs.." -o "..exec_name)
|
||||
if c ~= 0 and c ~= nil then
|
||||
print("Compilation Error")
|
||||
print("GIVEN UP")
|
||||
return c
|
||||
end
|
||||
return 0
|
||||
end,
|
||||
install = function()
|
||||
e,h,c = execute("cp "..exec_name.." /bin")
|
||||
return c or 0
|
||||
end,
|
||||
uninstall = function()
|
||||
e,h,c = execute("rm /bin"..exec_name)
|
||||
return c or 0
|
||||
end,
|
||||
}
|
||||
}
|
||||
243
flagpole/src/main.c
Normal file
243
flagpole/src/main.c
Normal file
|
|
@ -0,0 +1,243 @@
|
|||
#include <stdio.h>
|
||||
#include <unistd.h>
|
||||
#include <ctype.h>
|
||||
#define LAZY_IMPL
|
||||
#include "lazy.h"
|
||||
#include "token.h"
|
||||
|
||||
bool is_int_literal(Lz_SB *sb) {
|
||||
for (int i = 0; i < sb->cnt; ++i) {
|
||||
char c = sb->data[i];
|
||||
if (!(isdigit(c) || (i == 0 && c == '-'))) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
bool is_float_literal(Lz_SB *sb) {
|
||||
for (int i = 0; i < sb->cnt-1; ++i) {
|
||||
char c = sb->data[i];
|
||||
if (!(isdigit(c) || (i == 0 && c == '-') || c == '.')) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
return sb->data[sb->cnt-1] == 'f';
|
||||
}
|
||||
|
||||
bool is_double_literal(Lz_SB *sb) {
|
||||
for (int i = 0; i < sb->cnt; ++i) {
|
||||
char c = sb->data[i];
|
||||
if (!(isdigit(c) || (i == 0 && c == '-') || c == '.')) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
bool is_hex_literal(Lz_SB *sb) {
|
||||
if (sb->data[0] != '0' || sb->data[1] != 'x') {
|
||||
return false;
|
||||
}
|
||||
for (int i = 2; i < sb->cnt; ++i) {
|
||||
char c = sb->data[i];
|
||||
if (c >= '0' && c <= '9') continue;
|
||||
if (c >= 'a' && c <= 'f') continue;
|
||||
if (c >= 'A' && c <= 'F') continue;
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
bool is_bin_literal(Lz_SB *sb) {
|
||||
if (sb->data[0] != '0' || sb->data[1] != 'b') {
|
||||
return false;
|
||||
}
|
||||
for (int i = 2; i < sb->cnt; ++i) {
|
||||
char c = sb->data[i];
|
||||
if (c == '0' && c == '1') continue;
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
bool SBeq(Lz_SB *sb, const char *cstr) {
|
||||
size_t l = strlen(cstr);
|
||||
if (l != sb->cnt) return false;
|
||||
return !memcmp(sb->data, cstr, l);
|
||||
}
|
||||
|
||||
static inline bool isKW(Lz_SB *sb) {
|
||||
return
|
||||
SBeq(sb, "proc")
|
||||
|| SBeq(sb, "endproc")
|
||||
|| SBeq(sb, "ld8")
|
||||
|| SBeq(sb, "st8")
|
||||
|| SBeq(sb, "dup")
|
||||
;
|
||||
}
|
||||
|
||||
int main(uint argc, char **argv) {
|
||||
int opt;
|
||||
FILE *inpfile = stdin;
|
||||
while ((opt = getopt(argc, argv, "f:")) != -1) {
|
||||
switch(opt) {
|
||||
case 'f':
|
||||
inpfile = fopen(optarg, "r");
|
||||
if (!inpfile) {
|
||||
printf("Failed to open file %s\n", optarg);
|
||||
exit(1);
|
||||
}
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
TokenKind currTokenKind;
|
||||
Lz_SB tokenAccumulator = {0};
|
||||
int counter = 0;
|
||||
bool isQuote = false;
|
||||
bool isProc = false;
|
||||
Lz_DA(int) labelStack = {0};
|
||||
char newchar;
|
||||
printf("include 'fvm.inc'\n");
|
||||
printf("define STACK_START 0x6000000000000000\n");
|
||||
printf("define STACK_SP 125\n");
|
||||
printf("org 0x4000000000000000\n");
|
||||
printf(" MovI64 STACK_SP, STACK_START\n");
|
||||
printf(" Call __fp_user_main\n");
|
||||
printf(" Halt\n");
|
||||
printf("macro pushstack reg\n");
|
||||
printf(" MovI64 124, 8\n");
|
||||
printf(" SubR64 STACK_SP, 124\n");
|
||||
printf(" St64 reg, STACK_SP\n");
|
||||
printf("end macro\n\n");
|
||||
printf("macro popstack reg\n");
|
||||
printf(" MovI64 124, 8\n");
|
||||
printf(" Ld64 reg, STACK_SP\n");
|
||||
printf(" AddR64 STACK_SP, 124\n");
|
||||
printf("end macro\n\n");
|
||||
while ((newchar = fgetc(inpfile)) != EOF) {
|
||||
++counter;
|
||||
if (isspace(newchar) && !isQuote) {
|
||||
if (tokenAccumulator.cnt == 0) continue;
|
||||
if (is_int_literal(&tokenAccumulator)) {
|
||||
currTokenKind = TOKEN_INTLIT;
|
||||
goto codegen;
|
||||
} else if (is_float_literal(&tokenAccumulator)) {
|
||||
currTokenKind = TOKEN_FLOATLIT;
|
||||
goto codegen;
|
||||
} else if (is_double_literal(&tokenAccumulator)) {
|
||||
currTokenKind = TOKEN_DOUBLELIT;
|
||||
goto codegen;
|
||||
} else if (is_hex_literal(&tokenAccumulator)) {
|
||||
currTokenKind = TOKEN_HEXLIT;
|
||||
goto codegen;
|
||||
} else if (is_bin_literal(&tokenAccumulator)) {
|
||||
currTokenKind = TOKEN_BINLIT;
|
||||
goto codegen;
|
||||
} else {
|
||||
currTokenKind = TOKEN_IDENTIFIER;
|
||||
if (isKW(&tokenAccumulator)) {
|
||||
currTokenKind = TOKEN_KEYWORD;
|
||||
}
|
||||
goto codegen;
|
||||
}
|
||||
}
|
||||
if (newchar == '"') {
|
||||
if (isQuote) {
|
||||
currTokenKind = TOKEN_STRINGLIT;
|
||||
isQuote = false;
|
||||
goto codegen;
|
||||
} else {
|
||||
if (tokenAccumulator.cnt != 0) {
|
||||
fprintf(stderr, "error %d\n", __LINE__);
|
||||
exit(1);
|
||||
} else {
|
||||
isQuote = true;
|
||||
}
|
||||
continue;
|
||||
}
|
||||
}
|
||||
lz_da_append(tokenAccumulator, newchar);
|
||||
continue;
|
||||
codegen:
|
||||
//printf("I must gen code i am now Amista Azozin\n");
|
||||
//printf("Token type: %d\n", currTokenKind);
|
||||
//printf("Tok: "LZ_STR_FMT"\n", LZ_STR_PRINTF(tokenAccumulator));
|
||||
switch (currTokenKind) {
|
||||
case TOKEN_KEYWORD: {
|
||||
if (SBeq(&tokenAccumulator, "proc")) {
|
||||
isProc = true;
|
||||
break;
|
||||
}
|
||||
if (SBeq(&tokenAccumulator, "endproc")) {
|
||||
printf(" Ret\n");
|
||||
printf("\n\n");
|
||||
break;
|
||||
}
|
||||
if (SBeq(&tokenAccumulator, "ld8")) {
|
||||
printf(" popstack 101\n");
|
||||
printf(" Ld8 102, 101\n");
|
||||
printf(" pushstack 102\n");
|
||||
break;
|
||||
}
|
||||
if (SBeq(&tokenAccumulator, "st8")) {
|
||||
printf(" popstack 101\n");
|
||||
printf(" popstack 102\n");
|
||||
printf(" St8 102, 101\n");
|
||||
break;
|
||||
}
|
||||
if (SBeq(&tokenAccumulator, "dup")) {
|
||||
printf(" popstack 106\n");
|
||||
printf(" pushstack 106\n");
|
||||
printf(" pushstack 106\n");
|
||||
break;
|
||||
}
|
||||
printf("Unknown keyword: "LZ_STR_FMT"\n",
|
||||
LZ_STR_PRINTF(tokenAccumulator));
|
||||
exit(1);
|
||||
}
|
||||
case TOKEN_IDENTIFIER: {
|
||||
if (isProc) {
|
||||
printf("__fp_user_"LZ_STR_FMT":\n",
|
||||
LZ_STR_PRINTF(tokenAccumulator));
|
||||
isProc = false;
|
||||
break;
|
||||
}
|
||||
// Iirc there's not a general thing for identifiers so just fail?
|
||||
fprintf(stderr, "Useless Identifier: "LZ_STR_FMT"\n",
|
||||
LZ_STR_PRINTF(tokenAccumulator));
|
||||
exit(0);
|
||||
}
|
||||
case TOKEN_INTLIT: {
|
||||
printf(" MovI64 103, "LZ_STR_FMT"\n",
|
||||
LZ_STR_PRINTF(tokenAccumulator));
|
||||
printf(" pushstack 103\n");
|
||||
break;
|
||||
}
|
||||
case TOKEN_HEXLIT: {
|
||||
printf(" MovI64 103, "LZ_STR_FMT"\n",
|
||||
LZ_STR_PRINTF(tokenAccumulator));
|
||||
printf(" pushstack 103\n");
|
||||
break;
|
||||
}
|
||||
case TOKEN_STRINGLIT: {
|
||||
printf(" Jmp endstring%d\n", counter);
|
||||
printf("string%d db '"LZ_STR_FMT"', 0\n",
|
||||
counter,
|
||||
LZ_STR_PRINTF(tokenAccumulator));
|
||||
printf("endstring%d:\n", counter);
|
||||
printf(" MovI64 100, string%d\n", counter);
|
||||
printf(" pushstack 100\n", counter);
|
||||
break;
|
||||
}
|
||||
default: {
|
||||
printf("Bad: %d\n", currTokenKind);
|
||||
exit(1);
|
||||
}
|
||||
}
|
||||
tokenAccumulator.cnt = 0;
|
||||
}
|
||||
}
|
||||
11
flagpole/src/token.h
Normal file
11
flagpole/src/token.h
Normal file
|
|
@ -0,0 +1,11 @@
|
|||
typedef enum {
|
||||
TOKEN_NULL,
|
||||
TOKEN_INTLIT,
|
||||
TOKEN_FLOATLIT,
|
||||
TOKEN_DOUBLELIT,
|
||||
TOKEN_HEXLIT,
|
||||
TOKEN_BINLIT,
|
||||
TOKEN_STRINGLIT,
|
||||
TOKEN_IDENTIFIER,
|
||||
TOKEN_KEYWORD
|
||||
} TokenKind;
|
||||
1
flagpole/tests/fvm.inc
Symbolic link
1
flagpole/tests/fvm.inc
Symbolic link
|
|
@ -0,0 +1 @@
|
|||
../../tests/fvm.inc
|
||||
14
flagpole/tests/hw.fp
Normal file
14
flagpole/tests/hw.fp
Normal file
|
|
@ -0,0 +1,14 @@
|
|||
proc main
|
||||
"H" ld8 0xCFFFFFFFFFFFFFFD st8
|
||||
"e" ld8 0xCFFFFFFFFFFFFFFD st8
|
||||
"l" ld8 0xCFFFFFFFFFFFFFFD st8
|
||||
"l" ld8 0xCFFFFFFFFFFFFFFD st8
|
||||
"o" ld8 0xCFFFFFFFFFFFFFFD st8
|
||||
" " ld8 0xCFFFFFFFFFFFFFFD st8
|
||||
"W" ld8 0xCFFFFFFFFFFFFFFD st8
|
||||
"o" ld8 0xCFFFFFFFFFFFFFFD st8
|
||||
"r" ld8 0xCFFFFFFFFFFFFFFD st8
|
||||
"l" ld8 0xCFFFFFFFFFFFFFFD st8
|
||||
"d" ld8 0xCFFFFFFFFFFFFFFD st8
|
||||
"!" ld8 0xCFFFFFFFFFFFFFFD st8
|
||||
endproc
|
||||
Loading…
Add table
Add a link
Reference in a new issue