~vdupras/duskos

a718f130d3891730da55f55306550609bb43170a — Virgil Dupras a month ago 082bdea
cc: allow calling Forth words from the system dict

Of course, if the signature is wrong, then all hell breaks loose, but let's live
on the risky side for now :)
4 files changed, 13 insertions(+), 5 deletions(-)

M fs/cc/ast.fs
M fs/cc/gen.fs
M fs/tests/cc/cc.fs
M fs/tests/cc/test.c
M fs/cc/ast.fs => fs/cc/ast.fs +1 -1
@@ 150,7 150,7 @@ ASTIDCNT wordtbl astdatatbl ( node -- node )
: newnode ( parent nodeid -- newnode )
  createnode ( parent node ) dup rot addnode ( node ) ;

: _err ( -- ) abort" parsing error" ;
: _err ( -- ) abort" ast error" ;
: _assert ( f -- ) not if _err then ;

\ Takes a token and returns the corresponding typedef (not AST type).

M fs/cc/gen.fs => fs/cc/gen.fs +7 -4
@@ 46,7 46,8 @@

\ cc/vm abstracts away the save/restore mechanism through oppush/oppop.

: _err ( node -- ) printast abort"  unexpected node" ;
: _err ( -- ) abort" gen error" ;
: _assert ( f -- ) not if _err then ;

alias noop gennode ( node -- ) \ forward declaration



@@ 219,9 220,11 @@ ASTIDCNT wordtbl gentbl ( node -- )
    dup selop1 gennode swap dup selop2 sf+>op op1<>op2 vmmov, ops$
    4 - swap nextsibling ?dup not until drop then
  \ find and call
  ( node ) ast.funcall.funcname ( name ) ast.unit.find
  dup _assert dup nodeid AST_FUNCTION = _assert
  ast.func.address vmcall>op1, ;
  ( node ) ast.funcall.funcname ( name )
  dup ast.unit.find ?dup if ( name fnode )
    nip dup nodeid AST_FUNCTION = _assert ast.func.address else ( name )
    find _assert then ( address )
  vmcall>op1, ;

: _ ( node -- ) gentbl over nodeid wexec ;
current to gennode

M fs/tests/cc/cc.fs => fs/tests/cc/cc.fs +1 -0
@@ 23,4 23,5 @@ cnoop ( no result! ) scnt 0 #eq
42 ptrari 46 #eq
array 52 #eq
global 1234 #eq
42 142 sysword 142 #eq
testend

M fs/tests/cc/test.c => fs/tests/cc/test.c +4 -0
@@ 83,3 83,7 @@ int global2[3] = {4, 5, 6};
int global() {
    return global1;
}
// "max" is a forth word defined in the system
int sysword(int a, int b) {
    return max(a, b);
}