/*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; }
/*Genera il codice per il nodo def_stat e controlla i vincoli semantici*/ Code def_stat(Pnode def_stat_node){ //Imposto le due parti del nodo Pnode type_node = def_stat_node->child; Pnode id_list_head_node = def_stat_node->child->brother; //Definisco la variabile che contiene il codice da ritornare Code def_stat_code ; def_stat_code.head = NULL; def_stat_code.tail = NULL; def_stat_code.size = 0; //Sintetizzo il type Pschema schema_type = type(type_node); //Ottengo la id_list int id_list_len; Pname id_list_name = id_list(id_list_head_node,&id_list_len); //Controllo gli errori semantici //id ripetuti Boolean repetition = repeated_names(id_list_name); if (repetition == TRUE){ semerror(def_stat_node,"More than one variable with the same name"); } //variabili già assegnate Pnode id_node; for (id_node = id_list_head_node; id_node!=NULL; id_node=id_node->brother) if (name_in_environment(valname(id_node))) semerror(id_node,"Variable already defined"); //Genero il codice per la definizione delle variabili e inserisco i nomi nel contesto for (id_node = id_list_head_node; id_node!=NULL; id_node=id_node->brother){ //Genero il codice dell'id Code id_code ; int spazio_da_allocare = get_size(schema_type); if (schema_type->type == TABLE) id_code = makecode1(T_NEWTAB,spazio_da_allocare); else id_code = makecode1(T_NEWATOM,spazio_da_allocare); //Inserisco il nome nell'ambiente insert_name_into_environment(valname(id_node)); //Inserisco il nome nella symbol table Pschema schema_symbol = clone_schema(schema_type); schema_symbol->name = valname(id_node); insert(*schema_symbol); //Appendo a def_stat_code l'id_code def_stat_code = appcode(def_stat_code,id_code); } return def_stat_code; }
Code read_stat(Pnode p) { Code result, specifiercode; int op; // Vincoli semantici Psymbol symbol = lookup(valname(p->child->brother)); if (symbol == NULL) semerror(p->child, "Unknown identifier"); if (p->child->child != NULL) { // Con specifier op = T_FGET; specifiercode = specifier(p->child); } else { op = T_GET; } Value v1; v1.ival = symbol->oid; Value v2; v2.sval = get_format(symbol->schema); result = makecode2(op, v1, v2); if (op == T_GET) return result; else return appcode(specifiercode, result); }
Code assign_stat(Pnode p) { Psymbol symbol; Code exprcode; Schema exprschema; /* assign_stat / / ID ---> expr */ // Semantica: Carico gli schemi di ID e expr symbol = lookup(valname(p->child)); if (symbol == NULL) semerror(p->child, "Undefined identifier in assignment"); exprcode = expr(p->child->brother, &exprschema); // Type checking: if (!type_equal(symbol->schema, &exprschema)) semerror(p->child->brother, "Incompatible types in assignment"); if (exprschema.next != NULL) free_schema(exprschema.next); Value v1; v1.ival = symbol->oid; return concode( exprcode, makecode1(T_STO, v1), endcode()); }
/* presvr4flg - check for pre-svr4 package names also ? */ int pkgnmchk(char *pkg, char *spec, int presvr4flg) { /* pkg is assumed to be non-NULL upon entry */ /* * this routine reacts based on the value passed in spec: * NULL pkg must be valid and may be a wildcard spec * "all" pkg must be valid and must be an instance * "x.*" pkg must be valid and must be an instance of "x" * "x*" pkg must be valid and must be an instance of "x" */ if (valname(pkg, ((spec == NULL) ? 1 : 0))) return (1); /* invalid or reserved name */ if ((spec == NULL) || (strcmp(spec, "all") == 0)) return (0); while (*pkg == *spec) { if ((strcmp(spec, WILD1) == 0) || (strcmp(spec, WILD2) == 0) || (strcmp(spec, WILD3) == 0)) break; /* wildcard spec, so stop right here */ else if (*pkg++ == '\0') return (0); /* identical match */ spec++; } if ((strcmp(spec, WILD1) == 0) || (strcmp(spec, WILD2) == 0)) if ((pkg[0] == '\0') || (pkg[0] == '.')) return (0); return (1); }
/*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; }
/*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; }
/*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; }
/*Ritorno lo schema dell'attr_decl*/ Pschema attr_decl(Pnode attr_decl_node){ #ifdef DEBUG_ATTR_DECL printf( "ATTR_DECL - enter\n"); #endif //Prendo i due figli del nodo Pnode type_node = attr_decl_node->child; Pnode id_node = attr_decl_node->child->brother; //Analizzo il tipo Pschema schema = atomic_type(type_node); //Dall'id_node prendo il nome e lo aggiungo a schema schema->name = valname(id_node); #ifdef DEBUG_ATTR_DECL printf( "ATTR_DECL - exit\n"); #endif return schema; }