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
|
||||
20
src/interp.c
20
src/interp.c
|
|
@ -133,6 +133,9 @@ int main(int argc, char **argv) {
|
|||
unsigned char inputs[9];
|
||||
for (size_t i = 0; i < inpcnt; ++i) {
|
||||
inputs[i] = memory_get8(xPc+i+1);
|
||||
if (DEBUG) {
|
||||
printf("X%d: 0x%8X\n", i, inputs[i]);
|
||||
}
|
||||
}
|
||||
xPc += 1;
|
||||
xPc += inpcnt;
|
||||
|
|
@ -171,12 +174,29 @@ int main(int argc, char **argv) {
|
|||
memory_set8(registers[addr], registers[src]&0xFF);
|
||||
break;
|
||||
}
|
||||
case 0x8C: { // St64
|
||||
unsigned char src = inputs[0];
|
||||
unsigned char addr = inputs[1];
|
||||
memory_set64(registers[addr], registers[src]);
|
||||
break;
|
||||
}
|
||||
case 0x93: { // Ld8
|
||||
unsigned char dst = inputs[0];
|
||||
unsigned char addr = inputs[1];
|
||||
if (DEBUG) {
|
||||
printf("Ld8\n");
|
||||
printf("Dst val: %8X\n", registers[dst]);
|
||||
printf("Addr val: %8X\n", registers[addr]);
|
||||
}
|
||||
registers[dst] = memory_get8(registers[addr]);
|
||||
break;
|
||||
}
|
||||
case 0x8D: { // Ld64
|
||||
unsigned char dst = inputs[0];
|
||||
unsigned char addr = inputs[1];
|
||||
registers[dst] = memory_get64(registers[addr]);
|
||||
break;
|
||||
}
|
||||
case 0x42: { // RSetF
|
||||
unsigned char reg = inputs[0];
|
||||
int64_t val = *(int64_t*)(®isters[reg]); //Fuckery
|
||||
|
|
|
|||
19
tests/cmp.asm
Normal file
19
tests/cmp.asm
Normal file
|
|
@ -0,0 +1,19 @@
|
|||
include "fvm.inc"
|
||||
|
||||
org 0x4000000000000000
|
||||
MovI64 r95, UART_TX
|
||||
MovI64 r2, 8
|
||||
MovI64 r3, 2
|
||||
MovI64 r4, 0x30 ; ascii for 0
|
||||
Cmp64 r2, r3
|
||||
JmpIP Greater
|
||||
LessEq:
|
||||
AddR64 r3, r4
|
||||
St8 r3, r95
|
||||
Jmp Ending
|
||||
Greater:
|
||||
AddR64 r2, r4
|
||||
; MovI64 r2, 0x38
|
||||
St8 r2, r95
|
||||
Ending:
|
||||
Halt
|
||||
|
|
@ -236,6 +236,18 @@ macro St8 dst, addr
|
|||
db addr
|
||||
end macro
|
||||
|
||||
macro Ld64 dst, addr
|
||||
db 0x8D
|
||||
db dst
|
||||
db addr
|
||||
end macro
|
||||
|
||||
macro St64 dst, addr
|
||||
db 0x8C
|
||||
db dst
|
||||
db addr
|
||||
end macro
|
||||
|
||||
macro AddR64 dst, src
|
||||
db 0x6E
|
||||
db dst
|
||||
|
|
@ -266,6 +278,12 @@ macro ModR64 dst, src
|
|||
db src
|
||||
end macro
|
||||
|
||||
macro Cmp64 A, B
|
||||
db 0x7D
|
||||
db A
|
||||
db B
|
||||
end macro
|
||||
|
||||
macro RSetF reg
|
||||
db 0x42
|
||||
db reg
|
||||
|
|
@ -291,12 +309,22 @@ macro JmpIZ addr
|
|||
JmpRIZ 127
|
||||
end macro
|
||||
|
||||
macro callR addr
|
||||
macro JmpRIP addr
|
||||
db 0xC3
|
||||
db addr
|
||||
end macro
|
||||
|
||||
macro JmpIP addr
|
||||
MovI64 127, addr
|
||||
JmpRIP 127
|
||||
end macro
|
||||
|
||||
macro CallR addr
|
||||
db 0x46
|
||||
db addr
|
||||
end macro
|
||||
|
||||
macro call val
|
||||
macro Call val
|
||||
MovI64 127, val
|
||||
db 0x46
|
||||
db 127
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue