From 02aa3f707bc106d4349c617074917a4e65508856 Mon Sep 17 00:00:00 2001 From: cannoli-fruit Date: Tue, 28 Jul 2026 22:26:30 -0400 Subject: [PATCH] Implemented negative numbers and more importantly glendasay --- flagpole/fvmstd.fp | 40 +++++++++++++++++++++ flagpole/src/main.c | 72 ++++++++++++++++++++++++++++++++++++- flagpole/tests/glendasay.fp | 38 ++++++++++++++++++++ flagpole/tests/negative.fp | 8 +++++ flagpole/tests/tempconv.fp | 33 +++++------------ src/interp.c | 37 +++++++++++++++++++ tests/fvm.inc | 24 +++++++++++++ 7 files changed, 226 insertions(+), 26 deletions(-) create mode 100644 flagpole/tests/glendasay.fp create mode 100644 flagpole/tests/negative.fp diff --git a/flagpole/fvmstd.fp b/flagpole/fvmstd.fp index 778561c..aa8cca9 100644 --- a/flagpole/fvmstd.fp +++ b/flagpole/fvmstd.fp @@ -26,6 +26,36 @@ proc getuint &val endproc +proc getint + 0 @val + 0 @char + 0 @isNegative + 0 @hasNumber + while 1 do + 0 @skip + :getchar @char + if &char 0x2D == &hasNumber not band then + 1 @isNegative + 1 @skip + endif + + if &char 0x30 i< &char 0x39 i> bor &skip not band then + if &isNegative then + 0 &val i- return + endif + &val return + endif + + if &skip not then + 1 @hasNumber + &val + 10 i* + &char 0x30 i- i+ + @val + endif + endwhile +endproc + proc putuint @val if &val 0 == then @@ -45,6 +75,16 @@ proc putuint endwhile endproc +proc putint + @val + if &val 0 i< then + 0x2D :putchar + 0 &val i- @val + endif + &val :putuint +endproc + + proc puts while dup ld8 0 == not do dup ld8 :putchar diff --git a/flagpole/src/main.c b/flagpole/src/main.c index e0ccc88..e687bea 100644 --- a/flagpole/src/main.c +++ b/flagpole/src/main.c @@ -105,6 +105,13 @@ static inline bool isKW(Lz_SB *sb) { || SBeq(sb, "u%") || SBeq(sb, "u>") || SBeq(sb, "u<") + || SBeq(sb, "i+") + || SBeq(sb, "i-") + || SBeq(sb, "i*") + || SBeq(sb, "i/") + || SBeq(sb, "i%") + || SBeq(sb, "i>") + || SBeq(sb, "i<") || SBeq(sb, "pop") || SBeq(sb, "$inc") ; @@ -303,6 +310,7 @@ codegen: printf(" JmpIE __iftail_%d\n", lbl); break; } + if (SBeq(&tokenAccumulator, "endif")) { commentStack(&labelStack); int lbl = lz_da_pop(labelStack); @@ -411,6 +419,68 @@ codegen: printf(" pushstack 112\n"); break; } + if (SBeq(&tokenAccumulator, "i+")) { + printf(" popstack 97\n"); + printf(" popstack 98\n"); + printf(" AddR64 98, 97\n"); + printf(" pushstack 98\n"); + break; + } + if (SBeq(&tokenAccumulator, "i-")) { + printf(" popstack 97\n"); + printf(" popstack 98\n"); + printf(" SubR64 98, 97\n"); + printf(" pushstack 98\n"); + break; + } + if (SBeq(&tokenAccumulator, "i*")) { + printf(" popstack 97\n"); + printf(" popstack 98\n"); + printf(" IMulR64 98, 97\n"); + printf(" pushstack 98\n"); + break; + } + if (SBeq(&tokenAccumulator, "i/")) { + printf(" popstack 97\n"); + printf(" popstack 98\n"); + printf(" IDivR64 98, 97\n"); + printf(" pushstack 98\n"); + break; + } + if (SBeq(&tokenAccumulator, "i%")) { + printf(" popstack 97\n"); + printf(" popstack 98\n"); + printf(" IModR64 98, 97\n"); + printf(" pushstack 98\n"); + break; + } + if (SBeq(&tokenAccumulator, "i>")) { + printf(" popstack 97\n"); + printf(" popstack 98\n"); + printf(" ICmp64 98, 97\n"); + printf(" JmpIP __Cmp%d\n", counter); + printf(" MovI64 112, 0\n"); + printf(" Jmp __DoneCmp%d\n", counter); + printf("__Cmp%d:\n", counter); + printf(" MovI64 112, 1\n"); + printf("__DoneCmp%d:\n", counter); + printf(" pushstack 112\n"); + break; + } + if (SBeq(&tokenAccumulator, "i<")) { + printf(" popstack 97\n"); + printf(" popstack 98\n"); + printf(" ICmp64 98, 97\n"); + printf(" JmpIN __Cmp%d\n", counter); + printf(" MovI64 112, 0\n"); + printf(" Jmp __DoneCmp%d\n", counter); + printf("__Cmp%d:\n", counter); + printf(" MovI64 112, 1\n"); + printf("__DoneCmp%d:\n", counter); + printf(" pushstack 112\n"); + break; + } + if (SBeq(&tokenAccumulator, "pop")) { printf(" popstack 113\n"); break; @@ -535,7 +605,7 @@ codegen: } case TOKEN_STRINGLIT: { printf(" Jmp endstring%d\n", counter); - printf("string%d db '"LZ_STR_FMT"', 0\n", + printf("string%d db \""LZ_STR_FMT"\", 0\n", counter, LZ_STR_PRINTF(tokenAccumulator)); printf("endstring%d:\n", counter); diff --git a/flagpole/tests/glendasay.fp b/flagpole/tests/glendasay.fp new file mode 100644 index 0000000..58e707c --- /dev/null +++ b/flagpole/tests/glendasay.fp @@ -0,0 +1,38 @@ +$inc fvmstd.fp + +proc main + " /----------------------\ " :puts :newline + 0 @skip + while &skip not do + " | " :puts + 0 @i + while &i 20 u< &skip not band do + :getchar @c + if &c 0x0A == &c 0x00 == &c 0xFF == bor bor then + 1 @skip + endif + if &skip not then + &c :putchar + &i 1 u+ @i + endif + endwhile + while &i 20 u< do + 0x20 :putchar + &i 1 u+ @i + endwhile + " |" :puts :newline + endwhile + " \----------------------/ " :puts :newline + " " :puts :newline + " \ " :puts :newline + " \ " :puts :newline + " (\ (\ " :puts :newline + " \\_\\__, " :puts :newline + " / \ " :puts :newline + " | . .\ " :puts :newline + " \ Y | " :puts :newline + " | ' / " :puts :newline + " / | " :puts :newline + " (( / " :puts :newline + " ``'-,_>UU " :puts :newline +endproc diff --git a/flagpole/tests/negative.fp b/flagpole/tests/negative.fp new file mode 100644 index 0000000..a659c1e --- /dev/null +++ b/flagpole/tests/negative.fp @@ -0,0 +1,8 @@ +$inc fvmstd.fp + +proc main + :getint + 0 2 i- i+ + :putint + :newline +endproc diff --git a/flagpole/tests/tempconv.fp b/flagpole/tests/tempconv.fp index 32c74e7..bbe29ad 100644 --- a/flagpole/tests/tempconv.fp +++ b/flagpole/tests/tempconv.fp @@ -1,38 +1,21 @@ $inc fvmstd.fp -proc mainvar - "Source Fahrenheit or Celsius (F/C): " :puts - :getchar @srcUnit - :getchar drop # newline pmo - if &srcUnit 0x43 == &srcUnit 0x63 == bor then - "Source Temp: " :puts :getuint @srcTemp - &srcTemp 9 u* 5 u/ 32 u+ @dstTemp - &srcTemp :putuint "*C == " :puts &dstTemp :putuint "*F" :puts :newline - return - endif - if &srcUnit 0x46 == &srcUnit 0x66 == bor then - "Source Temp: " :puts :getuint @srcTemp - &srcTemp 32 u- 5 u* 9 u/ @dstTemp - &srcTemp :putuint "*F == " :puts &dstTemp :putuint "*C" :puts :newline - return - endif - "Invalid Unit" :puts :newline -endproc - proc main "Source Fahrenheit or Celsius (F/C): " :puts :getchar :getchar drop # newline pmo if dup 0x43 == dup 0x63 == bor then - "Source Temp: " :puts :getuint - dup 9 u* 5 u/ 32 u+ - swap :putuint "*C == " :puts :putuint "*F" :puts :newline + "Source Temp: " :puts :getint + dup 9 i* 5 i/ 32 i+ + swap :putint "*C == " :puts + :putint "*F" :puts :newline return endif if dup 0x46 == dup 0x66 == bor then - "Source Temp: " :puts :getuint - dup 32 u- 5 u* 9 u/ - swap :putuint "*F == " :puts :putuint "*C" :puts :newline + "Source Temp: " :puts :getint + dup 32 i- 5 i* 9 i/ + swap :putint "*F == " :puts + :putint "*C" :puts :newline return endif "Invalid Unit" :puts :newline diff --git a/src/interp.c b/src/interp.c index a030efd..8707474 100644 --- a/src/interp.c +++ b/src/interp.c @@ -219,6 +219,19 @@ int main(int argc, char **argv) { negativeFlag = (valA < valB); break; } + case 0x7F: { // ICmp64 + unsigned char regA = inputs[0]; + unsigned char regB = inputs[1]; + + int64_t valA = registers[regA]; + int64_t valB = registers[regB]; + + zeroFlag = (valA == valB); + parityFlag = (valA-valB)&1; + positiveFlag = (valA > valB); + negativeFlag = (valA < valB); + break; + } case 0x41: { // Not64 unsigned char reg = inputs[0]; registers[reg] = ~registers[reg]; @@ -266,6 +279,14 @@ int main(int argc, char **argv) { registers[dst] *= registers[src]; break; } + case 0x71: { // IMulR64 + unsigned char dst = inputs[0]; + unsigned char src = inputs[1]; + int64_t rdst = registers[dst]; + int64_t rsrc = registers[src]; + registers[dst] = rdst * rsrc; + break; + } case 0x72: { // DivR64 unsigned char dst = inputs[0]; unsigned char src = inputs[1]; @@ -273,12 +294,28 @@ int main(int argc, char **argv) { registers[dst] /= registers[src]; break; } + case 0x73: { // IDivR64 + unsigned char dst = inputs[0]; + unsigned char src = inputs[1]; + int64_t rdst = registers[dst]; + int64_t rsrc = registers[src]; + registers[dst] = rdst / rsrc; + break; + } case 0x74: { // ModR64 unsigned char dst = inputs[0]; unsigned char src = inputs[1]; registers[dst] %= registers[src]; break; } + case 0x75: { // IModR64 + unsigned char dst = inputs[0]; + unsigned char src = inputs[1]; + int64_t rdst = registers[dst]; + int64_t rsrc = registers[src]; + registers[dst] = rdst % rsrc; + break; + } case 0xC0: { // Jmp unsigned char addr = inputs[0]; xPc = registers[addr]; diff --git a/tests/fvm.inc b/tests/fvm.inc index d433090..74317ad 100644 --- a/tests/fvm.inc +++ b/tests/fvm.inc @@ -284,24 +284,48 @@ macro MulR64 dst, src db src end macro +macro IMulR64 dst, src + db 0x71 + db dst + db src +end macro + macro DivR64 dst, src db 0x72 db dst db src end macro +macro IDivR64 dst, src + db 0x73 + db dst + db src +end macro + macro ModR64 dst, src db 0x74 db dst db src end macro +macro IModR64 dst, src + db 0x75 + db dst + db src +end macro + macro Cmp64 A, B db 0x7D db A db B end macro +macro ICmp64 A, B + db 0x7F + db A + db B +end macro + macro Not64 reg db 0x41 db reg