Beispiel #1
0
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;	
}	
Beispiel #2
0
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;
}