Пример #1
0
Code stat_list(Pnode p)
{
    int env_num_vars = 0;
    push_environment();
/*
    stat_list
      /
     /
    stat --> stat --> stat
*/
    Code s = stat(p->child);
    // Scorro gli stats, dal secondo in poi
    for (p = p->child->brother; p != NULL; p = p->brother)
    {
        s = appcode(s, stat(p));
    }

    // Tolgo le variabili dichiarate in questo environment:
    if ((env_num_vars = numobj_in_current_env()) > 0)
    {
        Value v1; v1.ival = env_num_vars;
        s = appcode(s, makecode1(T_POP, v1));
    }
    pop_environment();
    return s;
}
Пример #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;
}
Пример #3
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;
}
Пример #4
0
Code write_stat(Pnode p)
{
    /*
         WRITE_STAT
            /
           /
        N_SPECIFIER --> expr
             /
            /
        [expr-filename]
     */
    Value format;
    int op;
    Schema exprschema;
    Code code = expr(p->child->brother, &exprschema);

    if (p->child->child != NULL)
    {
        // Con specifier
        code = appcode(code, specifier(p->child));
        op = T_FPRINT;
    }
    else
    {
        // Senza specifier
        op = T_PRINT;
    }
    format.sval = get_format(&exprschema);
    free_schema(exprschema.next);
    return concode(
        code,
        makecode1(op, format),
        endcode()
        );
}
Пример #5
0
Code tuple_const(Pnode p, Pschema s)
{
    Pschema schema;
    // Scorro tutti gli elementi della tupla
    Code result = endcode();
    Pnode elem;
    for (elem = p->child; elem != NULL; elem = elem->brother)
    {
        Code elemcode;
        switch (elem->type)
        {
            case N_INTCONST:
            case N_BOOLCONST:
                elemcode = makecode1(T_IATTR, elem->value); break;
            case N_STRCONST:
                elemcode = makecode1(T_SATTR, elem->value); break;
            default: noderror(elem);
        }
        if (result.head == NULL)
            result = elemcode;
        else
            result = appcode(result, elemcode);
    }

    // Type checking
    schema = tuple_to_schema(p);
    if (!type_equal(schema, s))
        semerror(p, "Incompatible tuples in table constant");
    free_schema(schema);

    return result;
}
Пример #6
0
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);
}
Пример #7
0
bool CBDS::startApp(const QString &filename, const QVariant &settings)
{
    QFile f(filename);
    if (f.open(QIODevice::ReadOnly))
    {
        QString appcode(f.readAll());
        f.close();
        m_cbo->reset();
        m_lastdraw = QVariantMap();
        m_engine.collectGarbage();
        if (settings.isValid())
            m_cbo->setSettings(m_engine.toScriptValue(settings));
        engageDebugger();
        if (!m_engine.evaluate(appcode, QFileInfo(filename).fileName()).isError())
        {
            if (m_clearchatonstart)
                m_chat.clear();
            m_chat.addLine(new ChatLine(QFileInfo(filename).baseName() + " app has started."));
            m_cbo->drawPanel();
            return true;
        }
        else
            return false;
    }
    emit error("Can't open file: " + filename);
    return false;
}
Пример #8
0
QVariant CBDS::getSettingsFromScript(const QString &filename)
{
    QFile f(filename);
    if (f.open(QIODevice::ReadOnly))
    {
        QString appcode(f.readAll());
        f.close();
        QScriptSyntaxCheckResult res = m_engine.checkSyntax(appcode);
        if (res.state() != QScriptSyntaxCheckResult::Valid)
        {
            emit error(QString("SyntaxCheck Failed: Line: %1 Column: %2: %3").arg(res.errorLineNumber()).arg(res.errorColumnNumber()).arg(res.errorMessage()));
            return QVariant();
        }

        QScriptContext *ctx = m_engine.pushContext();
        CBJSObject js;
        CBObjectBase cbo(&m_engine, m_roomowner);
        ctx->activationObject().setProperty("cb", m_engine.newQObject(&cbo));
        ctx->activationObject().setProperty("cbjs", m_engine.newQObject(&js));
        QScriptValue ret = m_engine.evaluate(appcode, QFileInfo(filename).fileName());
        if (ret.isError())
        {
            emit error(ret.toString());
            m_engine.popContext();
            return QVariant();
        }

        m_engine.popContext();
        return cbo.getSettingsChoices().toVariant();
    }
    emit error("Can't open file: " + filename);
    return QVariant();
}
Пример #9
0
Code concode(Code code1, Code code2, ...)
{
    Code rescode = code1, *pcode = &code2;

    while (pcode->head != NULL)
    {
        rescode = appcode(rescode, *pcode);
        pcode++;
    }
    return rescode;
}
Пример #10
0
/*Genera il codice per il nodo stat_list e crea lo scope del programma*/
Code stat_list(Pnode stat_list_node){
	//Definisco la variabile che contiene il codice da ritornare
	Code stat_list_code;
	stat_list_code.head = NULL;
	stat_list_code.tail = NULL;
	stat_list_code.size = 0;

	//Creo l'ambiente del programma
	push_environment();
	
	//Punto al primo stat
	Pnode stat_node = stat_list_node->child;
	//Ciclo lungo tutti gli stat_node
	while (stat_node!=NULL){
		//Creo il codice dello stat_node
		Code stat_code;
		switch (stat_node->type){
			case(N_DEF_STAT): 	stat_code = def_stat(stat_node);break;
			case(N_ASSIGN_STAT): 	stat_code = assign_stat(stat_node);break;
			case(N_IF_STAT): 	stat_code = if_stat(stat_node);break;
			case(N_WHILE_STAT): 	stat_code = while_stat(stat_node);break;
			case(N_READ_STAT): 	stat_code = read_stat(stat_node);break;
			case(N_WRITE_STAT): 	stat_code = write_stat(stat_node);break;
		}
		
		//Appendo il codice a stat_list_code
		stat_list_code = appcode(stat_list_code,stat_code);

		//Punto al fratello successivo
		stat_node = stat_node->brother;
	}
	
	//Appendo il codice per fare il pop dell'environment a stat_list_code
	if(numobj_in_current_env()!=0)
		stat_list_code = appcode(stat_list_code,makecode1(T_POP,numobj_in_current_env()));

	//elimino l'ambiente creato (elimina già le variabili dall'ambiente)
	pop_environment();

	return stat_list_code;
}
Пример #11
0
/*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;
}
Пример #12
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;
}
Пример #13
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;
}
Пример #14
0
Code def_stat(Pnode p)
{
/*
    def_stat
      /
     /
   type ---> ID ---> ID
*/
    int num_id = 0, op;
    Code c_temp, code_ret;
    Pname names;
    Pnode nodo_type = p->child;
    Pschema schema;

    switch (nodo_type->type)
    {
        case N_ATOMIC_TYPE:
            op = T_NEWATOM;
            break;
        case N_TABLE_TYPE:
            op = T_NEWTAB;
            break;
        default:
            noderror(p->child);
    }

    /* Operazioni comuni tra dati atomici e table */

    // Carico la lista di ID delle variabili
    names = id_list(p->child->brother, &num_id);

    // Vincoli semantici
    if (repeated_names(names))
        semerror(p, "Variable redeclaration");

    // Controlliamo che nessuna variabile sia nell'environment
    Pname n;
    for (n = names; n != NULL; n = n->next)
    {
        if (name_in_environment(n->name))
            semerror(p, "Variable redeclaration");
        // Aggiungo la nuova variabile nell'environment
        insert_name_into_environment(n->name);
    }

    // Genero il codice per allocare ognuna delle variabili
    code_ret.head = NULL;
    for (n = names; n != NULL; n = n->next)
    {
        // Aggiungo il nome alla Symbol Table
        schema = type(nodo_type);
        schema->name = n->name;
        insert(schema);

        Value v1; v1.ival = get_size(schema);
        c_temp = makecode1(op, v1);
        code_ret = (code_ret.head == NULL ? c_temp : appcode(code_ret, c_temp));
    }

    // Liberiamo la memoria
    free_name_list(names);

    return code_ret;
}