Example #1
0
VM * VM_fromBytecode (FILE *stream) {
  int glob_c, prog_len, i;
  Program *p;
  VM *vm;

  if (fscanf (stream, "%d:%d", &glob_c, &prog_len) < 2) {
    fprintf (stderr, "Bytecode format error\n"
                     "Expected glob_count:prog_size:opcode1:...:opcodeN\n");
    exit (EXIT_FAILURE);
  }

  p = Program_new (prog_len);
  vm = VM_new (p, glob_c);
  Program_destroy (p);

  for (i = 0; i < prog_len; i++) {
    if (fscanf (stream, ":%d", &vm->mem[i]) < 1) {
      fprintf (stderr, "Bytecode format error\n"
                       "Expected glob_count:prog_size:opcode1:...:opcodeN\n");
      exit (EXIT_FAILURE);
    }
  }


  return vm;
}
Example #2
0
/* a helper function to clean up the program before exit */
void cleanup_sish(void)
{    
    /* close open history file */
    if (fclose(historyptr) != 0) {
	printerr(debugLevel, "fail to close the history file\n");
	return;
    }

    /* delete history file */
    if (remove(historyfilename) != 0) {
	printerr(debugLevel, "fail to delete the history file\n");
	return;
    }

    /* close open batch file */
    if (fflag) {
	if (fclose(batchfileptr) != 0) {
	    printerr(debugLevel, "fail to close the batch file\n");
	    return;
	}
    }

    /* free string variables */
    assert(shellpath != NULL);
    free(shellpath);
    
    /* free the memory space for the array storing local variables */
    destroy_localVar();

    /* free created program structs */
    for (int i = 0; i < MAXNUMOFPROS; i++) {
	if (programs[i] != NULL) {
	    Program_destroy(programs[i]);
	}
    }
}
Example #3
0
/* unit testing */
int main(int argc, char *argv[])
{
    /* parsecml test */
    printf("\nparsecml test:\n");
    parsecml(argc - 1, argv + 1);

    printf("dflag: %d\n", dflag);
    printf("xflag: %d\n", xflag);
    printf("fflag: %d\n", fflag);
    printf("debugLevel: %d\n", debugLevel);
    printf("filename: %s\n", batchfile);
    for (int i = 0; filearg[i] != NULL; i++) {
        printf("filearg[%d]: %s\n", i, filearg[i]);
    }


    /* printerr test */
    printf("\n\nprinterr test:\n\n");
    char *errorstr = "This is an error";
    printerr(debugLevel, errorstr);


    /* program struct test */
    printf("\nprogram struct test:\n");
    char *test_argv[3];
    test_argv[0] = "myprog";
    test_argv[1] = "arg1";
    test_argv[2] = "arg2";
    Program *p = Program_create(3, test_argv, 1, 1, "F2", "F1");
    Program_print(p);
    Program_destroy(p);


    /* tokcml test */
    printf("\ntolcml test:\n");
    char *input = "ls -alg   | wc | cat | more";
    char **tokens;

    tokcml(input, &tokens);
    for (int i = 0; tokens[i] != NULL; i++) {
        printf("tokens[%d]: %s\n", i, tokens[i]);
    }


    /* pipe setter and getter test */
    printf("\npipesetter and getter test:\n");
    setNumOfPipes(tokens);
    printf("The number of pipes is: %d\n", getNumOfPipes());


    /* arguments reader test */
    printf("\narguments reader test 1:\ninput: %s\n", input);
    getArgs(tokens);
    for (int i = 0; programs[i] != NULL; i++) {
        Program_print(programs[i]);
    }
    token_destroy(tokens);


    /* arguments reader test 2 */
    input = "myprog arg1 arg2 < F1 > F2";
    printf("\narguments reader test 2:\ninput: %s\n", input);
    tokcml(input, &tokens);
    setNumOfPipes(tokens);
    getArgs(tokens);
    for (int i = 0; programs[i] != NULL; i++) {
        Program_print(programs[i]);
    }
    token_destroy(tokens);


    /* arguments reader test 3 */
    input = "< F1 > F2 myprog arg1 arg2";
    printf("\narguments reader test 3:\ninput: %s\n", input);
    tokcml(input, &tokens);
    setNumOfPipes(tokens);
    getArgs(tokens);
    for (int i = 0; programs[i] != NULL; i++) {
        Program_print(programs[i]);
    }
    token_destroy(tokens);


    /* arguments reader test 4 */
    input = "< F1 myprog arg1 arg2 > F2";
    printf("\narguments reader test 4:\ninput: %s\n", input);
    tokcml(input, &tokens);
    setNumOfPipes(tokens);
    getArgs(tokens);
    for (int i = 0; programs[i] != NULL; i++) {
        Program_print(programs[i]);
    }
    token_destroy(tokens);


    /* arguments reader test 5 */
    input = "prog1 arg1 arg2 | prog2 | prog3 arg1";
    printf("\narguments reader test 5:\ninput: %s\n", input);
    tokcml(input, &tokens);
    setNumOfPipes(tokens);
    getArgs(tokens);
    for (int i = 0; programs[i] != NULL; i++) {
        Program_print(programs[i]);
    }
    token_destroy(tokens);


    /* arguments reader test 6 */
    input = "prog1 arg1";
    printf("\narguments reader test 6:\ninput: %s\n", input);
    tokcml(input, &tokens);
    setNumOfPipes(tokens);
    getArgs(tokens);
    for (int i = 0; programs[i] != NULL; i++) {
        Program_print(programs[i]);
    }
    token_destroy(tokens);


    /* clean up */
    for (int i = 0; i < MAXNUMOFPROS; i++) {
        if (programs[i] != NULL) {
            Program_destroy(programs[i]);
        }
    }
}
Example #4
0
int main (int argc, char* argv[]) {
  int i = 1;
  FILE *alvcin = NULL;
  Node *ast = NULL;
  SymTable *st = NULL;
  Program *p = NULL;
  int exit_status = EXIT_SUCCESS;

  struct {
    enum { COMPILE, EXEC, BYTECODE, TRACE } mode;
    char *out, *in;
  } options = { COMPILE, NULL, NULL };

  progname = basename (argv[0]);

  if (!(argc == 2 && arg("-h")) && argc < 3)
    fatal ("not enough arguments (run with -h)");

  if (arg("-h")) {
    puts (
      "alvc -- the Awesome L Virtual machine and Compiler\n"
      "  usage: alvc mode input [output]\n"
      "    mode:   may be either -c (compile), -x (execute),\n"
      "            -b (execute bytecode), -t (trace) ou -h (help)\n"
      "    input:  input file in L or in bytecode\n"
      "    output: output file, defaults to /dev/stdout (only for -c/-t)"
    );
    exit (EXIT_SUCCESS);
  }
  else if (arg("-c")) options.mode = COMPILE;
  else if (arg("-x")) options.mode = EXEC;
  else if (arg("-b")) options.mode = BYTECODE;
  else if (arg("-t")) options.mode = TRACE;
  else                fatal ("unknwon mode");

  yyfile     = argv[++i];
  options.in = yyfile;

  if (argv[++i]) options.out = argv[i];

  alvcin = fopen (options.in,  "r");
  if (NULL == alvcin) {
    fprintf (stderr, "unable to open %s for reading (%s)\n",
             options.in, strerror (errno));
    exit (errno);
  }
  yyin = alvcin;

  if (EXEC != options.mode && BYTECODE != options.mode && NULL != options.out) {
    stdout = freopen (options.out, "w+", stdout);
    if (NULL == stdout) {
      fprintf (stderr, "unable to open %s for writing (%s)\n",
               options.out, strerror (errno));
      exit (errno);
    }
  }

  if (options.mode != BYTECODE) {
    next_token ();
    ast = rule_program ();

    st = SymTable_new (
      Node_countType (ast, N_VAR_DEC) +
      Node_countType (ast, N_FUN_DEC) +
      Node_countType (ast, N_ARR_DEC)
    );
    SymTable_build (st, ast);
    if (SymTable_hasFailed (false)) exit(EXIT_FAILURE);

    p = AST_compile (ast, st);
  }

  switch (options.mode) {
  case COMPILE:
    Program_dump (p, st);
    break;
  case EXEC:
    runvm (VM_new (p, SymTable_globalSize (st)), p, &exit_status);
    break;
  case BYTECODE: {
    VM *vm = VM_fromBytecode (alvcin);
    runvm (vm, (p = VM_extractProgram (vm)), &exit_status);
    } break;
  case TRACE:
    SymTable_print (st);
    Program_print (p);
    break;
  }

  if (NULL != p)   Program_destroy (p);
  if (NULL != st)  SymTable_destroy (st);
  if (NULL != ast) Node_destroy (ast);

  fclose (alvcin);

  exit (exit_status);
}