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];
|
unsigned char inputs[9];
|
||||||
for (size_t i = 0; i < inpcnt; ++i) {
|
for (size_t i = 0; i < inpcnt; ++i) {
|
||||||
inputs[i] = memory_get8(xPc+i+1);
|
inputs[i] = memory_get8(xPc+i+1);
|
||||||
|
if (DEBUG) {
|
||||||
|
printf("X%d: 0x%8X\n", i, inputs[i]);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
xPc += 1;
|
xPc += 1;
|
||||||
xPc += inpcnt;
|
xPc += inpcnt;
|
||||||
|
|
@ -171,12 +174,29 @@ int main(int argc, char **argv) {
|
||||||
memory_set8(registers[addr], registers[src]&0xFF);
|
memory_set8(registers[addr], registers[src]&0xFF);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
case 0x8C: { // St64
|
||||||
|
unsigned char src = inputs[0];
|
||||||
|
unsigned char addr = inputs[1];
|
||||||
|
memory_set64(registers[addr], registers[src]);
|
||||||
|
break;
|
||||||
|
}
|
||||||
case 0x93: { // Ld8
|
case 0x93: { // Ld8
|
||||||
unsigned char dst = inputs[0];
|
unsigned char dst = inputs[0];
|
||||||
unsigned char addr = inputs[1];
|
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]);
|
registers[dst] = memory_get8(registers[addr]);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
case 0x8D: { // Ld64
|
||||||
|
unsigned char dst = inputs[0];
|
||||||
|
unsigned char addr = inputs[1];
|
||||||
|
registers[dst] = memory_get64(registers[addr]);
|
||||||
|
break;
|
||||||
|
}
|
||||||
case 0x42: { // RSetF
|
case 0x42: { // RSetF
|
||||||
unsigned char reg = inputs[0];
|
unsigned char reg = inputs[0];
|
||||||
int64_t val = *(int64_t*)(®isters[reg]); //Fuckery
|
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
|
db addr
|
||||||
end macro
|
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
|
macro AddR64 dst, src
|
||||||
db 0x6E
|
db 0x6E
|
||||||
db dst
|
db dst
|
||||||
|
|
@ -266,6 +278,12 @@ macro ModR64 dst, src
|
||||||
db src
|
db src
|
||||||
end macro
|
end macro
|
||||||
|
|
||||||
|
macro Cmp64 A, B
|
||||||
|
db 0x7D
|
||||||
|
db A
|
||||||
|
db B
|
||||||
|
end macro
|
||||||
|
|
||||||
macro RSetF reg
|
macro RSetF reg
|
||||||
db 0x42
|
db 0x42
|
||||||
db reg
|
db reg
|
||||||
|
|
@ -291,12 +309,22 @@ macro JmpIZ addr
|
||||||
JmpRIZ 127
|
JmpRIZ 127
|
||||||
end macro
|
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 0x46
|
||||||
db addr
|
db addr
|
||||||
end macro
|
end macro
|
||||||
|
|
||||||
macro call val
|
macro Call val
|
||||||
MovI64 127, val
|
MovI64 127, val
|
||||||
db 0x46
|
db 0x46
|
||||||
db 127
|
db 127
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue