Skip to content
Snippets Groups Projects
fml.c 4.42 KiB
Newer Older
#include <stdio.h>
#include <string.h>
#include <stddef.h>
#include <ctype.h>
michal's avatar
michal committed

#include "arena.h"
#include "parser.h"
#include "ast_interpreter.h"
#include "bc_interpreter.h"
michal's avatar
michal committed

#define AST_INTERPRETER_COMMAND "ast_interpret"
#define BC_INTERPRETER_COMMAND "bc_interpret"
#define RUN "run"
#define HEAP_SIZE_COMMAND "--heap-size"
#define HEAP_LOG_COMMAND "--heap-log"

#define DEFAULT_HEAP_SIZE 550

int main ( int argc, char **argv ) {
	if ( argc < 2 ) {
		fprintf( stderr, "Input error: expected at least one argument\n" );
  size_t heap_size = DEFAULT_HEAP_SIZE;
  char * log_file = NULL;

  u8 ast_interpreter = 0;
  u8 bc_interpreter = 0;
  int f = -1;
  for ( int arg = 1; arg < argc; ++arg ) {
    len = strlen ( argv [ arg ] );
    for ( size_t j = 0; j < len; j++ )
      argv [ arg ] [ j ] = tolower ( argv [ arg ] [ j ] );
    if ( len == strlen ( AST_INTERPRETER_COMMAND ) && strncmp ( argv [ arg ], AST_INTERPRETER_COMMAND, len ) == 0 ) {
      ast_interpreter = 1;
      f = ++arg;
    } else if ( len == strlen ( BC_INTERPRETER_COMMAND ) && strncmp ( argv [ arg ], BC_INTERPRETER_COMMAND, len ) == 0 ) {
      bc_interpreter = 1;
    } else if ( len == strlen ( BC_COMPILER_COMMAND ) && strncmp ( argv [ arg ], BC_COMPILER_COMMAND, len ) == 0 ) {
      bc_compiler = 1;
      f = ++arg;
    } else if ( len == strlen ( RUN ) && strncmp ( argv [ arg ], RUN, len ) == 0 ) {
Michal Štěpánek's avatar
Michal Štěpánek committed
      size_t remaining_args = (size_t) argc - arg;
      for ( size_t opt = 0; opt < ( remaining_args > 2 ? 2 : remaining_args); ++opt ) {
        len = strlen ( argv [ ++arg ] );
        if ( len == strlen ( HEAP_SIZE_COMMAND ) && strncmp ( argv [ arg ], HEAP_SIZE_COMMAND, len ) == 0 ) {
          heap_size = atoi ( argv [ ++arg ] );
          if ( heap_size == 0 ) {
		        fprintf( stderr, "Input error: invalid heap size %s.\n", argv [ arg ] );
            flag = 2;
          }
        } else if ( len == strlen ( HEAP_LOG_COMMAND ) && strncmp ( argv [ arg ], HEAP_LOG_COMMAND, len ) == 0 ) {
          log_file = argv [ ++arg ];
        }
      }
      f = ++arg;
    } else {
		  fprintf( stderr, "Input error: unknown argument %s.\n", argv [ arg ] );
  if ( flag || f <= 0 ) 
  FILE * fp = fopen ( argv [ f ], "r" );
  if ( ! fp ) {
    fprintf ( stderr, "Input error: file does not exists.\n" );
    return 1;
  }

  if ( fseek ( fp, 0, SEEK_END ) ) {
    fprintf ( stderr, "Input error: could not advance to the end of the file.\n" );
    return 1;
  }

  int file_len = ftell ( fp );
  if ( file_len < 0 ) {
    fprintf ( stderr, "Input error: could not count the size of the file.\n" );
    return 1;
  }
  
  size_t flen = file_len;

  rewind ( fp );

  u8 * buffer = malloc ( flen );
  if ( fread ( buffer, 1, flen, fp ) != flen ) {
    fprintf ( stderr, "Input error: could not read to the file.\n" );
    return 1;
  }

  fclose ( fp );

  Str file_str = (Str) { .str = buffer, .len = flen };
  
  if ( ast_interpreter ) {
	  Arena arena;
	  arena_init( &arena );
	  Ast *ast = parse_src ( &arena, file_str );
	  if ( ast == NULL ) {
	  	fprintf ( stderr, "Failed to parse source\n" );
	  	arena_destroy ( &arena );
	  	return 1;
	  }
    ASTInterpreterState state;
    Heap heap;
    heap_init ( &heap, heap_size * 1024 * 1024 );
    state_init ( &state, &heap );
    evaluate ( &state, ast );
    state_destroy ( &state );
	  arena_destroy( &arena );
  String bc;
  if ( bc_compiler ) {
	  Arena arena;
	  arena_init( &arena );

	  Ast *ast = parse_src ( &arena, file_str );

	  if ( ast == NULL ) {
	  	fprintf ( stderr, "Failed to parse source\n" );
	  	arena_destroy ( &arena );
	  	return 1;
	  }
Michal Štěpánek's avatar
Michal Štěpánek committed
    bc = generate_bc ( ast );
	  arena_destroy( &arena );
  }
  if ( bc_interpreter ) {
      file_str = (Str) { .len = bc . len, .str = bc . str };
    VM vm;
    vm_init ( &vm, heap_size * 1024 * 1024 );
    vm_destroy ( &vm );
  if ( bc_compiler ) {
    if ( ! bc_interpreter )
      for ( size_t i = 0; i < bc . len; ++i ) {
        //printf ( "%c", bc . str [ i ] );
        printf ( "%u ", bc . str [ i ] );
      }
      //printf ( "%.*s", (int) bc . len, bc . str );
Michal Štěpánek's avatar
Michal Štěpánek committed
    string_destroy ( & bc );
  free ( buffer );