示例#1
0
void SymbolCheckVisitor::visit(ASTFunction& ast)
{
   ScopedScope scope(mScopeStack);
   ScopedValue<ASTFunction*> scopedfunction(&mpFunction, &ast, mpFunction);
   ASSERT_PTR(mpFunction);

   visitChildren(ast); // <-- arguments

   if ( ast.isConstructor() && ast.getName() != mpClass->getName() )
   {
      error(E0005, UTEXT("Function ") + ast.getName() + UTEXT(" must have a return type (or equal class name as constructor)."), ast);
   }

   if ( ast.hasBody() )
   {
      if ( ast.getModifiers().isAbstract() )
      {
         error(E0006, UTEXT("Abstract function ") + ast.getName() + UTEXT(" should not have a body."), ast);
      }
      else
      {
         checkReturn(ast);

         ast.getBody().accept(*this);
      }
   }
   else if ( !ast.getModifiers().isAbstract() && !ast.getModifiers().isPureNative() )
   {
      error(E0007, UTEXT("Function ") + ast.getName() + UTEXT(" requires a body."), ast);
   }

   mCurrentType.clear();
}
void ResourceCheckVisitor::visit(ASTFunction& ast)
{
   if ( !ast.getModifiers().isPureNative() && !ast.getModifiers().isAbstract() )
   {
      mOffset = 0;

      ast.getBody().accept(*this);
    
      ast.setLocalVariableCount(mOffset - ast.getArguments().size());
   }
}
示例#3
0
void OOCheckVisitor::visit(ASTFunction& ast)
{
   mpFunction = &ast;

   ScopedScope scope(mScopeStack);

   ast.getArgumentNodes().accept(*this);

   if ( ast.hasAnnotations() )
   {
      if ( ast.getAnnotations().contains(UTEXT("override")) )
      {
         // check if the base class still has this function
      }
   }

   if ( ast.isConstructor() )
   {
      // abstract classes can not have native constructors
      /*
      if ( ast.getModifiers().isNative() && mpClass->getModifiers().isAbstract() )
      {
         mContext.getLog().error("Abstract class " + mpClass->getFullName() + " can not have native constructors.");
      }
      */
   }
   else
   {
      if ( mpClass->hasBaseClass() )
      {
         ASTClass& baseclass = mpClass->getBaseClass();
         ASTFunction* pbasefunc = baseclass.findExactMatch(ast.getName(), ast.getSignature());
         if ( pbasefunc != NULL )
         {
            ast.setBaseFunction(*pbasefunc);
         }
      }
   }

   if ( ast.hasBody() )
   {
      mHasNativeCall = false;

      ast.getBody().accept(*this);

      if ( mHasNativeCall )
      {
         ast.getModifiers().setNative(true);
      }
   }
}
void CodeGeneratorVisitor::visit(ASTFunction& ast)
{
   CIL::Function* pfunction = new CIL::Function();
   pfunction->setName(ast.getName());
   pfunction->setReturnType(toCilType(ast.getType()));
   pfunction->setModifiers(toCilModifiers(ast.getModifiers()));

   // copy the arguments
   const ASTNodes& nodes = ast.getArgumentNodes();
   for ( int index = 0; index < nodes.size(); ++index )
   {
      const ASTFunctionArgument& arg = static_cast<const ASTFunctionArgument&>(nodes[index]);
      pfunction->addArgument(toCilType(arg.getVariable().getType()));
   }

   if ( ast.hasAnnotations() )
   {
      const ASTAnnotations& annotations = ast.getAnnotations();
      for ( int index = 0; index < annotations.size(); ++index )
      {
         const ASTAnnotation& anno = annotations[index];
         pfunction->addAnnotation(anno.mName);
      }
   }
   
   if ( !ast.getModifiers().isPureNative() )
   {
      mCurrentType.clear();

      if ( ast.hasBody() )
      {
         mpFunction = &ast;

         mBuilder.start();

         ScopedScope scope(mScopeStack);
         const ASTBlock& block = ast.getBody();
         block.accept(*this);

         mBuilder.end();

         // set the generated content
         pfunction->setInstructions(mBuilder.getInstructions());
         pfunction->setGuards(mBuilder.getGuards());
         pfunction->setSwitchTables(mBuilder.getSwitchTables());
      }

      // copy the locals
      const ASTTypeList& locals = ast.getLocals();
      for ( int index = 0; index < locals.size(); ++index )
      {
         const ASTType& local = locals[index];
         yasc::Type* ptype = yasc::Type::fromString(local.toString());
         pfunction->addLocal(ptype);
      }
      
      // clean up the code body to save memory
      ast.cleanup();
   }

   mpClass->getCompiledClass().add(pfunction);
}