commit d500f29ba56b38180cca8c7a3f9be1367746be2c
parent e25e72d199a6b7ad1f412af0e222ad044b2d707b
Author: Virgil Dupras <hsoft@hardcoded.net>
Date: Tue, 21 Jun 2022 07:04:21 -0400
cc: drop requirement for logical operators to shortcut
It makes cc/gen too complex and I'm not sure if this feature is worth it. When
I begin porting C apps, maybe I'll want to add it back, but for now, simplicity
is sought more actively...
Diffstat:
4 files changed, 14 insertions(+), 20 deletions(-)
diff --git a/fs/asm.fs b/fs/asm.fs
@@ -89,7 +89,7 @@ $00e9 op jmp, $0f84 op jz, $0f85 op jnz,
dup @ swap 4 + c@ swap modrm1, ;
4 $f7 op mul, 3 $f7 op neg, 2 $f7 op not,
1 $ff op dec, 0 $ff op inc,
-0 $0f9f op setg, 0 $0f9c op setl, 0 $0f94 op setz,
+0 $0f9f op setg, 0 $0f9c op setl, 0 $0f94 op setz, 0 $0f95 op setnz,
\ Two operands
: op ( immop immreg regop -- ) doer c, c, c, does> ( imm? a -- )
@@ -98,6 +98,7 @@ $00e9 op jmp, $0f84 op jz, $0f85 op jnz,
dup 1+ c@ ( immreg ) swap 2 + c@ ( immreg immop ) modrm<imm, else
c@ src swap ( reg regop ) modrm2, then ;
$81 0 $01 op add, $81 7 $39 op cmp, $81 5 $29 op sub, $f7 0 $85 op test,
+$81 4 $21 op and, $81 1 $09 op or,
\ tgt or-ed in
: op ( op -- ) doer c, does> ( a -- ) c@ tgtid or c, asm$ ;
diff --git a/fs/cc/gen.fs b/fs/cc/gen.fs
@@ -67,21 +67,6 @@ BOPSCNT wordtbl bopgentblpre ( node -- node )
'w noop ( || )
'w noop ( = )
-BOPSCNT wordtbl bopgentblmiddle ( node -- node )
-'w noop ( + )
-'w noop ( - )
-'w noop ( * )
-'w noop ( / )
-'w noop ( < )
-'w noop ( > )
-'w noop ( <= )
-'w noop ( >= )
-'w noop ( == )
-'w noop ( != )
-:w ( && ) vmjz, swap ;
-:w ( || ) vmjnz, swap ;
-'w noop ( = )
-
BOPSCNT wordtbl bopgentblpost ( -- )
'w vmadd, ( + )
'w vmsub, ( - )
@@ -93,8 +78,8 @@ BOPSCNT wordtbl bopgentblpost ( -- )
:w ( >= ) abort" TODO" ;
'w vm==, ( == )
:w ( != ) abort" TODO" ;
-'w vmjmp! ( && )
-'w vmjmp! ( || )
+'w vm&&, ( && )
+'w vm||, ( || )
:w ( = ) op2>*op1 ;
ASTIDCNT wordtbl gentbl ( node -- )
@@ -129,8 +114,7 @@ ASTIDCNT wordtbl gentbl ( node -- )
r@ childcount 2 = not if abort" binop node with more than 2 children!" then
r@ bopgentblpre r@ data1 wexec ( node )
firstchild dup nextsibling swap ( n2 n1 )
- selop1 gennode bopgentblmiddle r@ data1 wexec
- selop2 gennode bopgentblpost r> data1 wexec
+ selop1 gennode selop2 gennode bopgentblpost r> data1 wexec
( reg? f ) if op1<>op2 selop1 oppop then ;
'w _err ( unused )
:w ( If )
diff --git a/fs/cc/vm.fs b/fs/cc/vm.fs
@@ -225,6 +225,10 @@ operands value 'curop
: unaryopprep op>reg opAsm ;
: vmneg, unaryopprep neg, ;
: vmnot, ( ~ ) unaryopprep not, ;
+: vmboolify, unaryopprep
+ opAsm test,
+ opAsm 0 i32 mov,
+ opAsm setnz, ;
: vmboolnot, unaryopprep
opAsm test,
opAsm 0 i32 mov,
@@ -255,6 +259,9 @@ operands value 'curop
selop1 opAsm 0 i32 mov, ;
: vm<, _ opAsm setl, ;
: vm==, _ opAsm setz, ;
+: _ ( 'w -- ) selop1 opAsm selop2 opAsm execute opdeinit selop1 vmboolify, ;
+: vm&&, ['] and, _ ;
+: vm||, ['] or, _ ;
: vmjmp! ( 'jump_addr -- ) here over - 4 - swap ! ;
: vmjmp, 0 jmp, here 4 - ;
: vmjz, ( -- addr )
diff --git a/fs/doc/cc.txt b/fs/doc/cc.txt
@@ -34,3 +34,5 @@ For this reason, the core of the language is very close to ANSI.
* tightened parsing requirements for simplification purposes
* "unsigned" always goes first
* no "signed" (always default), no "auto"
+* No logical shortcut guarantee. In (a && b), b will be executed even if a
+ yields 0.