diff --git a/libs/base/System.idr b/libs/base/System.idr index 55188d88c..cb8711069 100644 --- a/libs/base/System.idr +++ b/libs/base/System.idr @@ -31,11 +31,13 @@ usleep sec = primIO (prim__usleep sec) -- Get the number of arguments %foreign "scheme:blodwen-arg-count" + support "idris2_getArgCount" "node:lambda:() => process.argv.length" prim__getArgCount : PrimIO Int -- Get argument number `n` %foreign "scheme:blodwen-arg" + support "idris2_getArg" "node:lambda:n => process.argv[n]" prim__getArg : Int -> PrimIO String diff --git a/src/Compiler/RefC/RefC.idr b/src/Compiler/RefC/RefC.idr index 67e79f447..9fa961fc3 100644 --- a/src/Compiler/RefC/RefC.idr +++ b/src/Compiler/RefC/RefC.idr @@ -928,12 +928,18 @@ header = do fns <- get FunctionDefinitions update OutfileText (appendL (initLines ++ headerLines ++ ["\n// function definitions"] ++ fns)) -footer : {auto il : Ref IndentLevel Nat} -> {auto f : Ref OutfileText Output} -> Core () +footer : {auto il : Ref IndentLevel Nat} + -> {auto f : Ref OutfileText Output} + -> {auto h : Ref HeaderFiles (SortedSet String)} + -> Core () footer = do emit EmptyFC "" emit EmptyFC " // main function" - emit EmptyFC "int main()" + emit EmptyFC "int main(int argc, char *argv[])" emit EmptyFC "{" + if contains "idris_support.h" !(get HeaderFiles) + then emit EmptyFC " idris2_setArgs(argc, argv);" + else pure () emit EmptyFC " Value *mainExprVal = __mainExpression_0();" emit EmptyFC " trampoline(mainExprVal);" emit EmptyFC " return 0; // bye bye" diff --git a/support/c/idris_support.c b/support/c/idris_support.c index 73f079f89..592d8e659 100644 --- a/support/c/idris_support.c +++ b/support/c/idris_support.c @@ -8,6 +8,9 @@ #include #include +int _argc; +char **_argv; + #ifdef _WIN32 extern char **_environ; #include "windows/win_utils.h" @@ -80,6 +83,19 @@ int idris2_time() { return time(NULL); // RTS needs to have 32 bit integers at least } +void idris2_setArgs(int argc, char *argv[]) { + _argc = argc; + _argv = argv; +} + +int idris2_getArgCount() { + return _argc; +} + +char* idris2_getArg(int n) { + return _argv[n]; +} + char* idris2_getEnvPair(int i) { return *(environ + i); } diff --git a/support/c/idris_support.h b/support/c/idris_support.h index 3947723fb..6f688d235 100644 --- a/support/c/idris_support.h +++ b/support/c/idris_support.h @@ -17,6 +17,9 @@ void idris2_sleep(int sec); void idris2_usleep(int usec); int idris2_time(); +int idris2_getArgCount(); +void idris2_setArgs(int argc, char *argv[]); +char* idris2_getArg(int n); char* idris2_getEnvPair(int i); long idris2_getNProcessors(); diff --git a/tests/Main.idr b/tests/Main.idr index 6ab6f98f1..19f86ad54 100644 --- a/tests/Main.idr +++ b/tests/Main.idr @@ -224,7 +224,7 @@ refcTests : TestPool refcTests = MkTestPool "Reference counting C backend" [C] [ "refc001" , "refc002" , "strings", "doubles" - , "buffer", "clock" + , "buffer", "clock", "args" ] racketTests : TestPool diff --git a/tests/refc/args/TestArgs.idr b/tests/refc/args/TestArgs.idr new file mode 100644 index 000000000..e9de8ede6 --- /dev/null +++ b/tests/refc/args/TestArgs.idr @@ -0,0 +1,6 @@ +module TestArgs + +import System + +main : IO () +main = getArgs >>= (putStrLn . show) diff --git a/tests/refc/args/expected b/tests/refc/args/expected new file mode 100644 index 000000000..ab327bf51 --- /dev/null +++ b/tests/refc/args/expected @@ -0,0 +1,2 @@ +["./build/exec/refc_args", "a", "b"] +["./build/exec/refc_args", "c"] diff --git a/tests/refc/args/run b/tests/refc/args/run new file mode 100644 index 000000000..cac0eb899 --- /dev/null +++ b/tests/refc/args/run @@ -0,0 +1,5 @@ +$1 --no-banner --no-color --console-width 0 --cg refc -o refc_args TestArgs.idr > /dev/null +./build/exec/refc_args a b +./build/exec/refc_args c + +rm -rf build