Beispiel #1
0
/**
 * @brief Insert a string in the string table
 * @param s The string to insert.
 * @return the pointer to ther string in the string table.
 */
char * insert_str_c(char * s){
    char *without = s;
    
    char * format_position = strstr(without, "\\n");
    while (format_position) {
        *format_position = '\n';
        ++format_position;
        memmove(format_position, format_position+1, strlen(format_position+1)+1);
        format_position = strstr(without, "\\n");
        
    }
    
    char * p_on_table = get_str_c(without);
    if (!p_on_table){
        int pos = hash_str_c(without);
        Str_c_node * new_node = (Str_c_node *)newmem(sizeof(Str_c_node));
        new_node->string = (char*)newmem(((int)strlen(without)+1) * sizeof(char));
        
        strcpy(new_node->string, without);
        p_on_table = new_node->string;
        new_node->next = str_const_table[pos];
        str_const_table[pos] = new_node;
    }
    return p_on_table;
}
Beispiel #2
0
/*Controlla la semantica della write e ne ritorna il codice*/
Code write_stat(Pnode write_stat_node){
	//Imposto le due parti del nodo
	Pnode specifier_node = write_stat_node->child;
	Pnode expr_node = write_stat_node->child->brother;

	//Definisco la variabile che contiene il codice da ritornare
	Code write_stat_code;
	
	//Calcolo il codice di specifier
	Pschema schema_specifier = (Pschema) newmem(sizeof(Schema));
	Code specifier_code = specifier(specifier_node,schema_specifier);

	//Controllo che non ci siano errori semantici
	//Controllo che il tipo di specifier sia corretto
	if (schema_specifier->type != STRING && schema_specifier->type != NIHIL)
		semerror(write_stat_node,"Expected string type");

	//Genero il codice di write_stat
	//Genero il codice di expr
	Pschema schema_expr = (Pschema) newmem(sizeof(Schema));
	Code expr_code = expr(expr_node,schema_expr);

	//La sintassi della write dipende dalla presenza dello specifier
	if (specifier_node->child == NULL)
		write_stat_code = appcode(expr_code,make_print_fprint(T_PRINT,get_format(*schema_expr)));
	else
		write_stat_code = concode(expr_code,specifier_code,make_print_fprint(T_FPRINT,get_format(*schema_expr)),endcode());

	return write_stat_code;
}
Beispiel #3
0
/**
 * @brief Allocate memory for the odescr adn put it on top of the ostack.
 *
 * If necessary expand the ostack.
 *
 * @return a pointer to the top of ostack.
 */
Odescr * push_ostack(){
    Odescr **old_ostack; int i;
    if(op == osize) {
        old_ostack = ostack;
        ostack = (Odescr**) newmem(sizeof(Odescr*)*(osize + OSTACK_UNIT));
        for(i = 0; i < osize; i++)
            ostack[i] = old_ostack[i];
        freemem((char*)old_ostack, sizeof(Odescr*)*osize);
        osize += OSTACK_UNIT;
    }
    return (ostack[op++] = (Odescr*)newmem(sizeof(Odescr)));
}
Beispiel #4
0
/**
 * @brief This function allocates memory for the adescr and puts it on top of the astack.
 *
 * If necessary it expands the astack.
 *
 * @return a pointer to the top of astack.
 */
Adescr * push_astack(){
    Adescr **old_astack; int i;
    if(ap == asize) {
        old_astack = astack;
        astack = (Adescr**) newmem(sizeof(Adescr*)*(asize + ASTACK_UNIT));
        for(i = 0; i < asize; i++)
            astack[i] = old_astack[i];
        freemem((char*)old_astack, sizeof(Adescr*)*asize);
        asize += ASTACK_UNIT;
    }
    return (astack[ap++] = (Adescr*)newmem(sizeof(Adescr)));
}
Beispiel #5
0
void exec_push(int num_objects, int return_address){
    Adescr *pa = push_astack();
    pa->num_objects = num_objects;
    pa->num_inited = 0;
    pa->return_address = return_address;
    pa->objects = (Odescr *)newmem(num_objects * sizeof(Odescr));
}
Beispiel #6
0
/*Controlla la semantica del nodo while e ne restituisce il codice*/
Code while_stat(Pnode while_stat_node){
	//Imposto le due parti del nodo	
	Pnode expr_node = while_stat_node->child;
	Pnode stat_list_node = while_stat_node->child->brother;

	//Definisco la variabile che contiene il codice da ritornare
	Code while_stat_code;

	//La generazione dell'ambiente viene fatta all'interno della funzione stat_list

	//Genero il codice di expr
	Pschema schema_expr = (Pschema) newmem(sizeof(Schema));
	Code expr_code = expr(expr_node,schema_expr);
	
	//Controllo i vincoli semantici
	if (schema_expr->type!=BOOLEAN)
		semerror(expr_node,"Expected boolean type");
	
	//Genero il codice di stat_list
	Code stat_list_code = stat_list(stat_list_node);
	//Calcolo gli offset
	int exit = stat_list_code.size + 2;
	int up = -(expr_code.size + stat_list_code.size + 1);
	
	//Genero il codice di while_stat
	while_stat_code = concode(expr_code,makecode1(T_SKIPF,exit),stat_list_code,makecode1(T_SKIP,up),endcode());

	return while_stat_code;
}
Beispiel #7
0
/*Controlla i vincoli semantici dell'assegnamento e ne ritorna il codice*/
Code assign_stat(Pnode assign_stat_node){
#ifdef DEBUG_ASSIGN_STAT
	printf("ASSIGN_STAT - enter\n");
#endif
	//Imposto le due parti del nodo	
	Pnode id_node = assign_stat_node->child;
	Pnode expr_node = assign_stat_node->child->brother;

	//Definisco la variabile che contiene il codice da ritornare
	Code assign_stat_code ;
	
	//Controllo i vincoli semantici
	//Visibilità del nome
	if (lookup(valname(id_node))==NULL)
		semerror(id_node,"Undefined variable");
	//Compatibilità degli schemi
	Pschema schema_expr = (Pschema) newmem(sizeof(Schema));
	Code expr_code = expr(expr_node,schema_expr);

	Psymbol symbol = lookup(valname(id_node)); 

	if (!type_equal((symbol->schema),*(schema_expr)))
		semerror(assign_stat_node,"Incompatible types");

	//Genero il codice
	assign_stat_code = appcode(expr_code,makecode1(T_STO,symbol->oid));

#ifdef DEBUG_ASSIGN_STAT
	printf("ASSIGN_STAT - exit\n");
#endif
	return assign_stat_code;
}
Beispiel #8
0
void exec_news(int size){
    Odescr *po;
    po = &top_astack()->objects[top_astack()->num_inited++];
    po->mode = STA;
    po->size = size;
    po->inst.sval = (char *)newmem(size * sizeof(char));
}
Beispiel #9
0
/**
 * @brief Increment the istack with the size and return the new top.
 *
 * If necessary expand the istack.
 *
 * @param size how much increment the istack.
 * @return a pointer to the top of istack.
 */
char * push_istack(int size){
    char *old_istack; int i, n;
    if(ip+size >= isize) {
        n = size/ISTACK_UNIT;
        old_istack = istack;
        istack = newmem(isize + ISTACK_UNIT);
        istack = newmem(isize + (n+1) * ISTACK_UNIT);
        for(i = 0; i < isize; i++)
            istack[i] = old_istack[i];
        freemem(old_istack, isize);
        isize += ISTACK_UNIT;
        isize += (n+1) * ISTACK_UNIT;
    }
    
    ip+=size;
    return &(istack[ip-size]);
}
Beispiel #10
0
/**
 * @brief This functin opens the input file and do the initial memory allocation of data structures.
 * @param input the s_code filename.
 */
void start_machine(char * input) {
    str_const_table = (Str_c_node **)newmem(sizeof(Str_c_node*)*STR_CONST_DIM);
    FILE *input_file = fopen(input, "r");
    if (!input_file){
        machine_error("ERRORE nel caricamento del file");
    }
    load_scode(input_file);
    fclose (input_file);
    
    pc = ap = op = ip = 0;
    astack = (Adescr**)newmem(sizeof(Adescr*)*ASTACK_UNIT);
    asize = ASTACK_UNIT;
    ostack = (Odescr**)newmem(sizeof(Odescr*)*OSTACK_UNIT);
    osize = OSTACK_UNIT;
    istack = (char*)newmem(ISTACK_UNIT);
    isize = ISTACK_UNIT;
}
Beispiel #11
0
Tstat *newstat(Operator op)
{
    Tstat *pstat;

    pstat = (Tstat*) newmem(sizeof(Tstat));
    pstat->address = 0;
    pstat->op = op;
    pstat->next = NULL;
    return pstat;
}
Beispiel #12
0
void exec_sil(int field_size){
    Odescr *op = pop_tstack();
    Odescr *op2 = push_tstack();
    op2->size = field_size;
    op2->mode = STA;
    op2->inst.sval = newmem(op2->size);
    memcpy(op2->inst.sval, op->inst.sval, op2->size);
    // only dealloc the object and not the inst
    freemem((char*)op, sizeof(Odescr));
}
Beispiel #13
0
char *update_lextab(char *s)
{
    int index;
    Pname p;
    char *ps;

    index = hash_function(s);
    for(p = lextab[index]; p != NULL; p = p->next)
    {
        if(strcmp(p->name, s) == 0)
            return(p->name);
    }
    ps = newmem(strlen(s)+1);
    strcpy(ps, s);
    p = lextab[index];
    lextab[index] = (Pname) newmem(sizeof(Name));
    lextab[index]->name = ps;
    lextab[index]->next = p;
    return(lextab[index]->name);
}
Beispiel #14
0
Pname id_list(Pnode p, int* quanti)
{
    if (p != NULL)
    {
        Pname lista = (Pname)newmem(sizeof(Name));
        lista->name = p->value.sval;

        (*quanti)++;
        lista->next = id_list(p->brother, quanti);
        return lista;
    }
    else return NULL;
}
Beispiel #15
0
void exec_cat(int num_fields, int size){
    int size_done = 0;
    int fields_done = 0;
    char *instance = newmem(size);
    while(fields_done < num_fields){
        Odescr *op = pop_tstack();
        int dest_start = size - size_done - op->size;
        // if there is an error reverse it, starting from 0 -- using size_done as index
        
        if(op->mode == EMB){
            switch(op->size){
                case sizeof(char): instance[dest_start] = op->inst.cval; break;
                case sizeof(int): *((int *)(instance+dest_start)) = op->inst.ival; break;
                case sizeof(char *):{
                    char *actual_address = instance+dest_start;
                    
                    char** act = (char **)actual_address;
                    act[0] = op->inst.sval;

                    //printf("%s %s\n",op->inst.sval, act[0]);
                    //printf("%p %s\n%p %s\n\n", act[0],act[0], op->inst.sval,op->inst.sval);
                    break;
                }
                default: machine_error("Unknown type for op->size"); break;
            }
        } else{
            memcpy(instance + dest_start, op->inst.sval, op->size);
        }
        size_done += op->size;
        fields_done++;
        free_odescr(op);
    }
    Odescr *op2 = push_tstack();
    op2->size = size;
    op2->mode = STA;
    op2->inst.sval = instance;
    // this allocates space on the instance stack and than copies byte by byte all the elements on the stack
    // taking them to the tstack (?)
    /*
        TSTACK:
        expr1_res
        expr2_res
        ...
    
        INSTANCE -> expr1_res, expr2_res, ...
    
        creates a single record on the tstack with SIZE, STA and with the pointer to the allocated instance
        
    */
}
Beispiel #16
0
Psymbol insert(Pschema schema)
{
    int index;
    Psymbol psymbol;

    index = hash_function(schema->name);
    psymbol = symtab[index];
    symtab[index] = (Psymbol) newmem(sizeof(Symbol));
    symtab[index]->oid = oid_counter++;
    symtab[index]->size = get_size(schema);
    symtab[index]->schema = schema;
    symtab[index]->next = psymbol;
    return(symtab[index]);
}
Beispiel #17
0
/*Riceve la testa della id_list e ritorna una lista di nomi più il numero di id presenti nella lista*/
Pname id_list(Pnode id_list_head, int *length){
	Pname head_name,id_name,prev_name;
	
	//Creo head_name e ne imposto i campi
	head_name = (Pname) newmem(sizeof(Name)); 
	head_name->name = valname(id_list_head);
	head_name->next = NULL;

	//Imposto il numero di id a 1
	*length = 1;
	
	//Punto al secondo id
	Pnode id = id_list_head->brother;

	//Salvo l'indirizzo di prev_name
	prev_name = head_name;
	while(id != NULL) {
		//Creo un nodo pname
		id_name = (Pname) newmem(sizeof(Name));

		//Imposto valname e next
		id_name->name = valname(id);
		id_name->next = NULL;
	
		//Imposto il puntatore al prossimo elemento della lista
		prev_name->next = id_name;

		//Incremento il numero di id
		*length = *length + 1;
		//Passo all'id successivo
		id = id->brother;
		//Prev_name punta all'ultimo nome nella lista
		prev_name = id_name;
	}
	return head_name;
}
Beispiel #18
0
/*Ritorna lo schema e imposta il tipo nel campo type di schema*/
Pschema atomic_type(Pnode atomic_type_node){
#ifdef DEBUG_ATOMIC_TYPE
	printf( "ATOMIC_TYPE_NODE - enter\n");
#endif
	//Creo lo schema
	Pschema schema = (Pschema) newmem(sizeof(Schema));
	//Imposto tutti i campi a null
	schema->name = NULL;
	schema->next = NULL;
	//Imposto il type
	schema->type = qualifier(atomic_type_node);
#ifdef DEBUG_ATOMIC_TYPE
	printf( "ATOMIC_TYPE_NODE - exit\n");
#endif
	return schema;
}
Beispiel #19
0
/*Genera lo schema della tupla e ritorna il codice*/
Code tuple_const(Pnode tuple_const_node,Pschema schema){
	//Non ci sono vincoli semantici
#ifdef DEBUG_TUPLE_CONST
	printf( "TUPLE_CONST - enter\n");
#endif
	//Preparo il codice della tupla
	Code tuple_const_code;
	tuple_const_code.head = NULL;
	

	//Punto al primo elemento della tupla
	Pnode atomic_const_node = tuple_const_node->child;

	//Preparo la variabile che contiene il codice dell'id
	Code atomic_const_code;
	Pschema prev_schema = schema;	
	do{
		//Calcolo il codice e lo schema della prima costante
		switch(atomic_const_node->type){
		case (N_INTCONST): 	atomic_const_code = makecode1(T_IATTR,qualifier(atomic_const_node));
					prev_schema->type = INTEGER;
					break;
		case (N_BOOLCONST):	atomic_const_code = makecode1(T_IATTR,qualifier(atomic_const_node));
					prev_schema->type = BOOLEAN;
					break;	
		case (N_STRCONST):	atomic_const_code = make_sattr(valname(atomic_const_node));
					prev_schema->type = STRING;
					break;
		}
	
		//Appendo il codice della costante al codice della tupla
		tuple_const_code = appcode(tuple_const_code,atomic_const_code);
		
		//Passo al fratello
		atomic_const_node = atomic_const_node->brother;	
		//Creo un nuovo schema
		if (atomic_const_node!=NULL){
			Pschema newSchema = (Pschema) newmem(sizeof(Schema));
			prev_schema->next = newSchema;
			prev_schema = prev_schema->next;
		}
	}while(atomic_const_node!=NULL);
#ifdef DEBUG_TUPLE_CONST
	printf( "TUPLE_CONST - exit\n");
#endif
	return tuple_const_code;
}
Beispiel #20
0
/*Controlla la semantica del nodo if e ne ritorna il codice*/
Code if_stat(Pnode if_stat_node){
#ifdef DEBUG_IF_STAT
	printf("IF_STAT - enter\n");
#endif
	//Imposto le tre parti del nodo	
	Pnode expr_node = if_stat_node->child;
	Pnode then_node = if_stat_node->child->brother;
	Pnode else_node = if_stat_node->child->brother->brother;
	
	//Definisco la variabile che contiene il codice da ritornare
	Code if_stat_code ;

	//La generazione dell'ambiente viene fatta all'interno della funzione stat_list
	
	//Genero il codice di expr
	Pschema schema_expr = (Pschema) newmem(sizeof(Schema));
	Code expr_code = expr(expr_node,schema_expr);
	
	//Controllo i vincoli semantici
	if (schema_expr->type!=BOOLEAN)
		semerror(expr_node,"Expected boolean type");

	//Genero il codice di then_node
	Code then_code = stat_list(then_node);
	
	if (else_node==NULL){//if then endif
		//Calcolo l'offset
		int offset = then_code.size + 1;
		//Genero il codice di if_stat
		if_stat_code = concode(expr_code,makecode1(T_SKIPF,offset),then_code,endcode());
	}
	else {//if then else
		//Genero il codice di else_node
		Code else_code = stat_list(else_node);
		//Calcolo gli offset
		int offset_then = then_code.size + 2;
		int offset_else = else_code.size + 1;
		//Genero il codice di if_stat
		if_stat_code = concode(expr_code,makecode1(T_SKIPF,offset_then),then_code,makecode1(T_SKIP,offset_else),else_code,endcode());

	}
#ifdef DEBUG_IF_STAT
	printf("IF_STAT - exit\n");
#endif	
	return if_stat_code;
}
Beispiel #21
0
/*
Ritorna lo schema del table_type.
*/
Pschema table_type(Pnode type_node){
#ifdef DEBUG_TABLE_TYPE
	printf( "TABLE_TYPE - enter\n");
#endif
	//Creo lo schema
	Pschema schema = (Pschema) newmem(sizeof(Schema));
	schema->name = NULL;

	//Imposto il type (che sarà TABLE)
	schema->type = qualifier(type_node);
	
	//Genero la lista di attributi
	schema->next = attr_list(type_node->child);
	
#ifdef DEBUG_TABLE_TYPE
	printf( "TABLE_TYPE - ok attr_list definition\n");
#endif
	return schema;
}
Beispiel #22
0
void* allocmem(size_t size)
{ void* result = safe_alloc(size);
  { long h; 
    
    { long i;
      h=hash(result);
      for (i=0; i<maxptrs; i++)
        if (ptr[h]==NULL) break;  else if (++h>=maxptrs) h=0;
      if (i==maxptrs) {
        /*error("Object table overflow (%ld). Try increasing 'maxobjects'.\n"
          ,chunks); */
        /* we're just going to dynamically grow the object table */
        newmem(3*maxptrs/2); /* increase maxptrs by 50% */
        free(result);
        return allocmem(size); /* safe to call again now */
      }
    }
    ignore_intr(); /* don't interrupt while updating |ptr| */
    ptr[h]=result; ++chunks; allow_intr();
  }
  return result;
}
Beispiel #23
0
char *get_format(Pschema schema)
{
    char *format;
    char *attr_name, *atomic_type;
    Boolean first = TRUE;
    
    format = (char*) newmem(MAXFORMAT);
    switch(schema->type)
    {
        case INTEGER: 
            sprintf(format, "i"); 
            break;
        case STRING: 
            sprintf(format, "s"); 
            break;
        case BOOLEAN: 
            sprintf(format, "b"); 
            break;
        case TABLE: 
            sprintf(format, "(");
            for(schema = schema->next; schema; schema = schema->next)
            {
                attr_name = (schema->name ? schema->name : "?");
                atomic_type = (schema->type == INTEGER ? "i" : (schema->type == STRING ? "s" : "b"));
                if(first == FALSE)
                    strcat(format, ",");
                sprintf(&format[strlen(format)], "%s:%s", attr_name, atomic_type);
                first = FALSE;
            }
            strcat(format, ")");
            break;
        default:
            syserror("get_format()");
    }
    return(format);
}
Beispiel #24
0
/*Controlla la semantica della read e ritorna il codice della read*/
Code read_stat(Pnode read_stat_node){
#ifdef DEBUG_READ_STAT
	printf("READ_STAT - enter\n");
#endif
	//Imposto le due parti del nodo
	Pnode specifier_node = read_stat_node->child;
	Pnode id_node = read_stat_node->child->brother;
	
	//Definisco il codice del nodo
	Code read_stat_code;
	read_stat_code.head = NULL;

	//Calcolo il codice di specifier
	Pschema schema_specifier = (Pschema) newmem(sizeof(Schema));
	Code specifier_code = specifier(specifier_node,schema_specifier);

	//Controllo che non ci siano errori semantici
	//Controllo che il tipo di specifier sia corretto
	if ((schema_specifier->type != STRING) && (schema_specifier->type != NIHIL))
		semerror(read_stat_node,"Expected string type");
	//Controllo che il nome dell'id sia visibile
	if (lookup(valname(id_node))==NULL)
		semerror(id_node,"Variable not defined");

	//Genero il codice di readstat
	//La sintassi della read dipende dalla presenza dello specifier
	Psymbol symbol = lookup(valname(id_node));
	if (specifier_node->child == NULL)		
		read_stat_code = make_get_fget(T_GET,symbol->oid,get_format((symbol->schema)));
	else
		read_stat_code = appcode(specifier_code,make_get_fget(T_FGET,symbol->oid,get_format((symbol->schema))));
#ifdef DEBUG_READ_STAT
	printf("READ_STAT - exit\n");
#endif
	return read_stat_code;
}