int lex_token( struct lexState *ls ) { char c = lex_next( ls ); int done = 0; if( c == TK_EOF ) { lex_settoken( ls, TK_EOF, 0 ); return TK_EOF; } for( ; c != TK_EOF && !done; ) { done = 1; switch( c ) { case '\n': case '\r': done = 0; ls->lineno ++; break; case ' ': case '\t': done = 0; break; case '>': { if( lex_next( ls ) == '=' ) { lex_settoken( ls, TK_GE, ">=" ); } else { lex_back( ls ); lex_settoken( ls, '>', ">" ); } } break; case '<': { if( lex_next( ls ) == '=' ) { lex_settoken( ls, TK_LE, "<=" ); } else { lex_back( ls ); lex_settoken( ls, '<', "<" ); } } break; case '=': { if( lex_next( ls ) == '=' ) { lex_settoken( ls, TK_EQ, "==" ); } else { lex_back( ls ); lex_settoken( ls, '=', "=" ); } } break; case '!': { if( lex_next( ls ) == '=' ) { lex_settoken( ls, TK_NE, "!=" ); } else { lex_back( ls ); lex_settoken( ls, '!', "!" ); } } break; case '|': { if( lex_next( ls ) == '|' ) { lex_settoken( ls, TK_OR, "||" ); } else { lex_settoken( ls, TK_ERROR, 0 ); ls->lex_error( ls->lineno, ">>lex error->expect '|'" ); } } break; case '&': { if( lex_next( ls ) == '&' ) { lex_settoken( ls, TK_AND, "&&" ); } else { lex_settoken( ls, TK_ERROR, 0 ); ls->lex_error( ls->lineno, ">>lex error->expect '&'" ); } } break; #define SINGLE_TOKEN( t, str ) \ case t: \ { \ lex_settoken( ls, t, str ); \ } \ break SINGLE_TOKEN( '[', "[" ); SINGLE_TOKEN( ']', "]" ); SINGLE_TOKEN( '(', "(" ); SINGLE_TOKEN( ')', ")" ); SINGLE_TOKEN( '{', "{" ); SINGLE_TOKEN( '}', "}" ); SINGLE_TOKEN( '+', "+" ); SINGLE_TOKEN( '-', "-" ); SINGLE_TOKEN( '*', "*" ); SINGLE_TOKEN( '%', "%" ); SINGLE_TOKEN( ',', "," ); SINGLE_TOKEN( ';', ";" ); case '\'': { int t = lex_read_char( ls ); if( t == TK_ERROR ) { ls->lex_error( ls->lineno, ">>lex error->read char constant error" ); } } break; case '"': { int t = lex_read_string( ls ); if( t == TK_ERROR ) { ls->lex_error( ls->lineno, ">>lex error->read string constant error" ); } } break; case '/': { if( lex_next( ls ) == '*' ) { char c; /* comment */ done = 0; do { if( ( c = lex_next( ls ) ) == '*' ) { if( lex_next( ls ) == '/' ) { break; } lex_back( ls ); } if( c == '\r' || c == '\n' ) { ls->lineno ++; } } while( c != TK_EOF ); } else { lex_back( ls ); lex_settoken( ls, '/', "/" ); } } break; default: { if( isdigit( c ) ) { lex_read_number( ls, c ); } else if( isalpha( c ) || c == '_' ) { int t; lex_read_id( ls, c ); /* check whether it's a reserved word */ if( ( t = lex_lookup_reserved( ls->token.string ) ) != 0 ) { ls->token.type = t; } } else { lex_settoken( ls, TK_ERROR, 0 ); ls->lex_error( ls->lineno, ">>lex error->unknown token character" ); } } } if( !done ) { c = lex_next( ls ); } } if( c == TK_EOF ) { lex_settoken( ls, TK_EOF, 0 ); } return ls->token.type; }
GC_USER_FUNC int main (int argc, char ** argv) { #ifdef MEMWATCH mwInit(); mwDoFlush(1); #endif // MEMWATCH ML_START_TIMING(main_time); GC_init(); //ml_print_gc_stats(); printf("Compiled for " #if defined(GC_CHERI) "GC_CHERI" #elif defined(GC_BOEHM) "GC_BOEHM" #elif defined(GC_NONE) "GC_NONE" #elif defined(GC_NOCAP) "GC_NOCAP" #else #error "Define one of GC_CHERI, GC_BOEHM, GC_NONE." #endif // GC_CHERI, GC_BOEHM, GC_NONE " at %s\n", __TIME__ " " __DATE__); //GC_CAP const char * filename = GC_cheri_ptr("ml-tmp", sizeof("ml-tmp")); //lex_read_file(filename); //const char str[] = "(fn x . ((fn x . x) 3) + x) 2"; //const char str[] = "fn f . (fn g. (f (fn a . (g g) a))) (fn g. (f (fn a . (g g) a)))"; //const char str[] = //"((fn f . fn n . if n then n * f (n-1) else 1) (fn n . n)) 5"; // factorial: //const char str[] = // "((fn f . (fn g. (f (fn a . (g g) a))) (fn g. (f (fn a . (g g) a)))) (fn f . fn n . if n then n * f (n-1) else 1)) 6"; // for the benchmark: if (argc < 2) { printf("Need a program argument\n"); return 1; } if (argc < 3) { printf("Need a number argument\n"); return 1; } printf("Program should be evaluating something to do with the number %s\n", argv[2]); int num = atoi(argv[2]); #ifdef GC_CHERI gc_cheri_grow_heap(num); #endif #ifdef GC_BOEHM GC_set_max_heap_size(num >= 1024 ? 350000*(num/1024) : num >= 256 ? 200000 : 65536); #endif /*const char str[] = "((fn f . (fn g. (f (fn a . (g g) a))) (fn g. (f (fn f . (g g) f)))) (fn f . fn n . if n then n + f (n-1) else 1)) "; GC_CAP char * str2 = ml_malloc(sizeof(str)+strlen(argv[1])); cmemcpy(str2, GC_cheri_ptr(str, sizeof(str)), sizeof(str)); cmemcpy(str2+sizeof(str)-1, GC_cheri_ptr(argv[1], strlen(argv[1]+1)), strlen(argv[1]+1)); */ GC_CAP const char * str2 = GC_cheri_ptr(argv[1], strlen(argv[1])+1); unsigned long long before = ml_time(); lex_read_string(str2); printf("program: %s\n\n", (void*)(str2)); /*size_t i; for (i=0; i<lex_state.max; i++) { putchar(((char*)lex_state.file)[i]); } GC_CAP token_t * t; t = lex(); while (t->type != TKEOF) { printf("[%d] (tag=%d alloc=%d) %s\n", ((token_t*)t)->type, (int) GC_cheri_gettag(((token_t*)t)->str), (int) GC_IS_GC_ALLOCATED(((token_t*)t)->str), (char*) ((token_t*)t)->str); GC_malloc(5000); t = lex(); } printf("Finished\n"); return 0;*/ parse_init(); GC_CAP expr_t * expr = GC_INVALID_PTR(); GC_STORE_CAP(expr, parse()); printf("AST:\n"); print_ast(expr); printf("\nDone printing AST\n"); /*printf("collecting loads\n"); ml_collect(); ml_collect(); ml_collect(); ml_collect(); ml_collect(); ml_collect(); ml_collect(); ml_collect(); ml_collect(); ml_collect(); ml_collect(); ml_collect(); ml_collect(); ml_collect(); ml_collect(); printf("~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~done collecting loads\n"); GC_debug_print_region_stats(&GC_state.thread_local_region);*/ GC_CAP val_t * val = GC_INVALID_PTR(); int i; for (i=0; i<10; i++) { GC_STORE_CAP(val, eval(expr, GC_INVALID_PTR())); } unsigned long long after = ml_time(); unsigned long long diff = after - before; printf("eval: "); if (!PTR_VALID(val)) printf("(invalid"); else print_val(val); printf("\n\n"); printf("[plotdata] %s %llu\n", argv[2], (unsigned long long) diff); #ifdef GC_CHERI printf("(young) heap size:\n"); printf("[altplotdata] %s %llu\n", argv[2], (unsigned long long) (GC_cheri_getlen(GC_state.thread_local_region.tospace))); #ifdef GC_GENERATIONAL printf("old heap size:\n"); printf("[altplotdataold] %s %llu\n", argv[2], (unsigned long long) (GC_cheri_getlen(GC_state.old_generation.tospace))); #endif // GC_GENERATIONAL #endif // GC_CHERI #ifdef GC_BOEHM printf("[altplotdata] %s %llu\n", argv[2], (unsigned long long) GC_get_heap_size()); #endif // GC_BOEHM ML_STOP_TIMING(main_time, "main()"); ml_print_gc_stats(); ml_print_plot_data(); #ifdef MEMWATCH mwTerm(); #endif // MEMWATCH return 0; }