Ejemplo n.º 1
0
static SymPtr LookupIdent(char **name)
{
	SymPtr sym=NULL,parent;
	
    /* check this class only */
	if( in_class && Token==tSELF )
	{
		SkipToken(tSELF);
		SkipToken(tPERIOD);
		*name = GetIdent();
		sym = SymFindLevel(*name,(SymGetScope()-1));
	}
    /* check super class only */
	else if( in_class && Token==tSUPER && base_class->super!=NULL )
	{
	    SkipToken(tSUPER);
	    SkipToken(tPERIOD);
	    *name = GetIdent();
	    sym = SymFindLocal(*name,base_class->super);
        
	    if( sym!=NULL && sym->flags&SYM_PRIVATE )
	    {
		    compileError("attempt to access private field '%s'",*name);
		    NextToken();
		    return COMPILE_ERROR;
	    }
	}
	/* check all super classes */
    else if( in_class )
	{
        *name = GetIdent();
        parent=base_class->super;
        while(parent!=NULL)
        {
            sym = SymFindLocal(*name,parent);
            if(sym!=NULL) break;
            parent=parent->super;
        }
	   	if( sym!=NULL && sym->flags&SYM_PRIVATE )
	    {
		    compileError("attempt to access private field '%s'",*name);
		    NextToken();
		    return COMPILE_ERROR;
	    }
	}
    
    /* check globals */
    if( sym==NULL )
	{
		*name = GetIdent();
		sym = SymFind(*name);
	}
    
	return sym;
}
Ejemplo n.º 2
0
SymEntry* FindSizeOfSymbol (SymEntry* Sym)
/* Get the size of a symbol table entry. The function returns the symbol table
 * entry that encodes the size of the symbol or NULL if there is no such entry.
 */
{
    return SymFindLocal (Sym, &SizeEntryName, SYM_FIND_EXISTING);
}
Ejemplo n.º 3
0
SymEntry* GetSizeOfSymbol (SymEntry* Sym)
/* Get the size of a symbol table entry. The function returns the symbol table
 * entry that encodes the size of the symbol and will create a new one if it
 * does not exist.
 */
{
    return SymFindLocal (Sym, &SizeEntryName, SYM_ALLOC_NEW);
}
Ejemplo n.º 4
0
static SymPtr FieldReference(SymPtr clas)
{
	SymPtr field,parent;
	char *fieldname;
	
	SkipToken(tPERIOD);
	fieldname = GetIdent();
	    
	/* lookup field in class and parents */
	parent=clas;
	while( parent!=NULL )
	{
		field = SymFindLocal(fieldname,parent);
		if( field!=NULL ) break;
		parent = parent->super;
	}

	if( field==NULL )
	{
		compileError("field '%s' not found",fieldname); 
		return NULL;
	}
	
	field->flags |= SYM_FIELD; /* MCC */
	
	if( field->flags&SYM_PRIVATE )
	{
		compileError("attempt to access private field '%s'",fieldname);
		return NULL;
	}
	
	if( field->flags&SYM_PROTECTED && !in_class )
	{
		compileError("attempt to access protected field '%s'",fieldname);
		return NULL;
	}

	NextToken();

	if( is_func_kind(field) )
    {
		return field;
    }
	
	if( is_global_kind(clas) )
	{
		vm_genI(op_getglobal,clas->num);
	}
	else if( is_local_kind(clas) )
	{
		vm_genI(op_getlocal,clas->num);
	}

	return field;
}
Ejemplo n.º 5
0
SymEntry* ParseAnySymName (SymFindAction Action)
/* Parse a cheap local symbol or a a (possibly scoped) symbol name, search
 * for it in the symbol table and return the symbol table entry.
 */
{
    SymEntry* Sym;

    /* Distinguish cheap locals and other symbols */
    if (CurTok.Tok == TOK_LOCAL_IDENT) {
        Sym = SymFindLocal (SymLast, &CurTok.SVal, Action);
        NextTok ();
    } else {
        Sym = ParseScopedSymName (Action);
    }

    /* Return the symbol found */
    return Sym;
}
Ejemplo n.º 6
0
static void AssignmentStatement(void)
{
    Int32 type,count;
	SymPtr sym,clas_init=NULL;
	SymPtr parents[16];

	sym = Lhs();

	if( sym==NULL )
	{
		return;
	}
    
    CheckClassMember(sym);

	SkipToken(tEQUALS);

	if(sym->flags&SYM_DEFINED)
	{
		compileError("cannot reassign constant");
		return;
	}
	else if(sym->flags&SYM_CONSTANT)
	{
		sym->flags |= SYM_DEFINED;
	}	

    /* CheckClassMember(sym); */
	
    new_class=NULL;
	type=Expr();
	
	sym->object.type = type;
		
	switch(sym->kind)
	{
	case LOCAL_KIND:
		vm_genI(op_setlocal,sym->num);
		break;
	
	case GLOBAL_KIND:
		vm_genI(op_setglobal,sym->num);
		break;

	case FIELD_KIND:
		vm_genI(op_setfield,sym->num);
		break;

	default: 
		compileError("invalid assignment");
		break;
	}

	if( type==CLASS_TYPE && new_class != NULL )
	{
        sym->clas = new_class;
  		sym->super = new_class->super;
    	sym->locals = new_class->locals;

		/* First build a list of all super classes */
		count=0;
		clas_init=sym;
		while( clas_init!=NULL )
		{
			parents[count++] = clas_init;
			clas_init = clas_init->super;
		}
		
		/* Now call all constructors in reverse order */
		count--;
		while( count>=0 )
		{
			clas_init = SymFindLocal(NEW,parents[count]);
			FunctionCall(clas_init,sym);
			vm_gen0(op_pop);
			count--;
		}

        /* call user defined constructor */
		clas_init=SymFindLocal("init",sym);
		if( clas_init!=NULL )
		{
    		if( (Token==tLPAREN && clas_init->nargs!=0) ||
                (Token!=tLPAREN && clas_init->nargs==0) )
		    {
				FunctionCall(clas_init,sym);
				vm_gen0(op_pop);
			}
		}
	}
}