Skip to content

Instantly share code, notes, and snippets.

@Minoru
Created October 29, 2010 22:57
Show Gist options
  • Save Minoru/654618 to your computer and use it in GitHub Desktop.
Save Minoru/654618 to your computer and use it in GitHub Desktop.
VERY simple Haskell shell to C translator
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/wait.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <errno.h>
int exec_command(const char**);
int exec_command(const char* cmd[]) {
/*
* Executes specified command
*
* Returns exit status of executed command, or, if command was killed by a
* signal, 128+signum, or -1 if fork() failed
*/
pid_t pid = fork();
if(pid == -1) {
perror("Error in fork()");
// returning -1 is bad, but what should I do?
return 126;
}
if(pid) {
int retval;
waitpid(pid, &retval, 0);
if(WIFEXITED(retval)) {
return WEXITSTATUS(retval);
} else {
// killed by signal
// return 128+number of signal that teminated our child
return 128 + WTERMSIG(retval);
}
} else {
execvp(cmd[0], (char * const*)cmd);
perror("Error in execvp()");
switch (errno) {
case EACCES:
_exit(127);
break;
default:
_exit(126);
}
}
return 0;
}
-- task1.hs
-- Task:
-- write a simple generator of C code (in Haskell)
--
-- Let's say you have a list of commands, each represented by a list of strings.
-- Write a Haskell function which would generate a complete C program executing
-- those commands.
--
-- As I said above, you might want to pull as much code as possible outside the
-- generator. To achieve this, create a C file ("library") with auxiliary
-- functions.
type Command = [String]
type C = String
genC :: [Command] -> C
genC (x:xs) = helper "" "" 0 (x:xs)
where helper :: C -> C -> Int -> [Command] -> C
helper definitions code n [] = "#include \"routines.h\"\nint main(){\n" ++ definitions ++ code ++ "}\n"
helper definitions code n (x:[]) = helper (definitions ++ "const char* cmd" ++ show n ++ "[] = { " ++ createArray x ++ "};\nint retval;\n") (code ++ "retval = exec_command (cmd" ++ show n ++ ");\nreturn retval;\n") (n+1) []
helper definitions code n (x:xs) = helper (definitions ++ "const char* cmd" ++ show n ++ "[] = { " ++ createArray x ++ "};\n") (code ++ "exec_command (cmd" ++ show n ++ ");\n") (n+1) xs
createArray :: Command -> C
createArray (x:[]) = "\"" ++ x ++ "\", NULL"
createArray (x:xs) = "\"" ++ x ++ "\", " ++ createArray xs
genC _ = ""
main = putStr (genC [["ping", "-c1", "google.com"], ["date"], ["tuch", "example.file"], ["ncal"], ["echo", "Hello, world!"]])
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment