 
 SYNTAX: C-INCLUDE: scan define-c-include ;
 
-SYNTAX: C-FUNCTION:
-    return-library-function-params define-c-function ;
+SYNTAX: C-FUNCTION: function-types-effect define-c-function ;
 
 SYNTAX: ;C-LIBRARY compile-c-library ;

    compile-library? [ compile-library ] when
    c-library get library-path "cdecl" add-library ;

: define-c-function ( return library function params -- )
    [ factor-function ] 4 nkeep c-function-string
    " {\n" append parse-here append "\n}\n" append
    c-strings get push ;

: define-c-link ( str -- )
    "-l" prepend compiler-args get push ;

SYMBOL: compiler-args
SYMBOL: c-strings

: function-types-effect ( -- function types effect )
    scan scan swap ")" parse-tokens
    [ "(" subseq? not ] filter parse-arglist ;

: types-effect>params-return ( types effect -- params return )
    [ nip out>> first ] [ in>> zip ] 2bi ;

: arg-list ( types -- params )
    CHAR: a swap length CHAR: a + [a,b]
    [ 1string ] map ;

: factorize-type ( str -- str' )
    "const-" ?head drop ;

: cify-type ( str -- str' )
    { { CHAR: ~ CHAR: space } } substitute ;

: factor-function ( function types effect -- )
    [ c-library get ] 3dip [ [ factorize-type ] map ] dip
    types-effect>params-return factorize-type -roll
    make-function define-declared ;

: prototype-string ( function types effect -- str )
    [ [ cify-type ] map ] dip
    types-effect>params-return cify-type -rot
    2 group [ " " join "," append ] map " " join
    "(" prepend ")" append 3array " " join
    library-is-c++ get [ "extern \"C\" " prepend ] when ;

: prototype-string' ( function types return -- str )
    [ dup arg-list ] <effect> prototype-string ;

: append-function-body ( prototype-str -- str )
    " {\n" append parse-here append "\n}\n" append ;


: library-path ( -- str )
    "lib" c-library get library-suffix
