Exemplo n.º 1
0
Arquivo: syntax.c Projeto: dnaeon/core
void CheckPromise(Promise *pp)
{
    char output[CF_BUFSIZE];

    if (strcmp(pp->agentsubtype, "vars") == 0)
    {
        char *data_type = NULL;
        Constraint *cp;

        for (cp = pp->conlist; cp != NULL; cp = cp->next)
        {
            if (IsDataType(cp->lval))
            {
                if (data_type != NULL)
                {
                    snprintf(output, CF_BUFSIZE,
                             "Variable contains existing data type contstraint %s, tried to redefine with %s",
                             data_type, cp->lval);
                    ReportError(output);
                    ERRORCOUNT++;
                }
                data_type = cp->lval;
            }
        }
    }
}
Exemplo n.º 2
0
bool asCParser::IsDeclaration()
{
	sToken t1, t2;

	GetToken(&t1);

	if( t1.type == ttConst )
	{
		RewindTo(&t1);
		return true;
	}

	if( !IsDataType(t1.type) )
	{
		RewindTo(&t1);
		return false;
	}

	GetToken(&t2);
	if( t2.type == ttIdentifier )
	{
		RewindTo(&t1);
		return true;
	}

	// The data type can be followed by handle and array brackets
	while( t2.type == ttHandle || t2.type == ttOpenBracket )
	{
		if( t2.type == ttOpenBracket )
		{
			GetToken(&t2);
			if( t2.type != ttCloseBracket )
			{
				RewindTo(&t1);
				return false;
			}
		}

		GetToken(&t2);
	}

	if( t2.type == ttIdentifier )
	{
		RewindTo(&t1);
		return true;
	}

	RewindTo(&t1);
	return false;
}
Exemplo n.º 3
0
asCScriptNode *asCParser::ParseDataType()
{
	asCScriptNode *node = new asCScriptNode(snDataType);

	sToken t1;

	GetToken(&t1);
	if( !IsDataType(t1.type) )
	{
		Error(TXT_EXPECTED_DATA_TYPE, &t1);
		return node;
	}

	node->SetToken(&t1);
	node->UpdateSourcePos(t1.pos, t1.length);

	return node;
}
Exemplo n.º 4
0
bool Disasm::ParsePCL6() {
	uint8 byte;
	while (fStream->ReadUByte(byte)) {
		if (IsOperator(byte)) {
			if (!DecodeOperator(byte)) return false;
		} else if (IsDataType(byte)) {
			if (!PushData(byte)) return false;
		} else if (IsAttribute(byte)) {
			bool ok = DecodeAttribute(byte);
			ClearAttrs();
			if (!ok) return false;
		} else if (IsEmbedData(byte)) {
			if (!DecodeEmbedData(byte)) return false;
		} else if (IsWhiteSpace(byte)) {
			// nothing to do
		} else if (IsEsc(byte)) {
			return true;
		} else {
			Error("Unknown byte in input stream");
			return false;
		}
	}
	return true;
}
Exemplo n.º 5
0
/**
 * @brief Collects variable constraints controlling how the promise should be converged
 */
static ConvergeVariableOptions CollectConvergeVariableOptions(EvalContext *ctx, const Promise *pp, bool allow_redefine)
{
    ConvergeVariableOptions opts = { 0 };
    opts.should_converge = false;
    opts.drop_undefined = false;
    opts.ok_redefine = allow_redefine;
    opts.cp_save = NULL;

    if (EvalContextPromiseIsDone(ctx, pp))
    {
        return opts;
    }

    if (!IsDefinedClass(ctx, pp->classes, PromiseGetNamespace(pp)))
    {
        return opts;
    }

    int num_values = 0;
    for (size_t i = 0; i < SeqLength(pp->conlist); i++)
    {
        Constraint *cp = SeqAt(pp->conlist, i);

        if (strcmp(cp->lval, "comment") == 0)
        {
            continue;
        }

        if (cp->rval.item == NULL)
        {
            continue;
        }

        if (strcmp(cp->lval, "ifvarclass") == 0)
        {
            Rval res;

            switch (cp->rval.type)
            {
            case RVAL_TYPE_SCALAR:

                if (!IsDefinedClass(ctx, cp->rval.item, PromiseGetNamespace(pp)))
                {
                    return opts;
                }

                break;

            case RVAL_TYPE_FNCALL:
                {
                    bool excluded = false;

                    /* eval it: e.g. ifvarclass => not("a_class") */

                    res = FnCallEvaluate(ctx, cp->rval.item, NULL).rval;

                    /* Don't continue unless function was evaluated properly */
                    if (res.type != RVAL_TYPE_SCALAR)
                    {
                        RvalDestroy(res);
                        return opts;
                    }

                    excluded = !IsDefinedClass(ctx, res.item, PromiseGetNamespace(pp));

                    RvalDestroy(res);

                    if (excluded)
                    {
                        return opts;
                    }
                }
                break;

            default:
                Log(LOG_LEVEL_ERR, "Invalid ifvarclass type '%c': should be string or function", cp->rval.type);
                continue;
            }

            continue;
        }

        if (strcmp(cp->lval, "policy") == 0)
        {
            if (strcmp(cp->rval.item, "ifdefined") == 0)
            {
                opts.drop_undefined = true;
                opts.ok_redefine = false;
            }
            else if (strcmp(cp->rval.item, "constant") == 0)
            {
                opts.ok_redefine = false;
            }
            else
            {
                opts.ok_redefine |= true;
            }
        }
        else if (IsDataType(cp->lval))
        {
            num_values++;
            opts.cp_save = cp;
        }
    }

    if (opts.cp_save == NULL)
    {
        Log(LOG_LEVEL_INFO, "Warning: Variable body for \"%s\" seems incomplete", pp->promiser);
        PromiseRef(LOG_LEVEL_INFO, pp);
        return opts;
    }

    if (num_values > 2)
    {
        Log(LOG_LEVEL_ERR, "Variable \"%s\" breaks its own promise with multiple values (code %d)", pp->promiser, num_values);
        PromiseRef(LOG_LEVEL_ERR, pp);
        return opts;
    }

    opts.should_converge = true;
    return opts;
}
Exemplo n.º 6
0
bool asCParser::IsFuncDecl(bool isMethod)
{
	// Set start point so that we can rewind
	sToken t;
	GetToken(&t);
	RewindTo(&t);

	// A class constructor can start with identifier followed by parenthesis
	if( isMethod )
	{
		sToken t1, t2;
		GetToken(&t1);
		GetToken(&t2);
		RewindTo(&t);
		if( t1.type == ttIdentifier && t2.type == ttOpenParanthesis )
			return true;
	}

	// A function decl can start with a const
	sToken t1;
	GetToken(&t1);
	if( t1.type == ttConst )
		GetToken(&t1);

	if( !IsDataType(t1.type) )
	{
		RewindTo(&t);
		return false;
	}

	// Object handles can be interleaved with the array brackets
	sToken t2;
	GetToken(&t2);
	while( t2.type == ttHandle || t2.type == ttOpenBracket )
	{
		if( t2.type == ttOpenBracket )
		{
			GetToken(&t2);
			if( t2.type != ttCloseBracket )
			{
				RewindTo(&t);
				return false;
			}
		}

		GetToken(&t2);
	}

	if( t2.type != ttIdentifier )
	{
		RewindTo(&t);
		return false;
	}

	GetToken(&t2);
	if( t2.type == ttOpenParanthesis ) 
	{	
		// If the closing paranthesis is not followed by a  
		// statement block then it is not a function. 
		while( t2.type != ttCloseParanthesis && t2.type != ttEnd )
			GetToken(&t2);

		if( t2.type == ttEnd ) 
			return false;
		else
		{
			GetToken(&t1);
			RewindTo(&t);
			if( t1.type == ttStartStatementBlock )
				return true;
		}

		RewindTo(&t);
		return false;
	}

	RewindTo(&t);
	return false;
}
Exemplo n.º 7
0
bool asCParser::IsVarDecl()
{
	// Set start point so that we can rewind
	sToken t;
	GetToken(&t);
	RewindTo(&t);
	
	// A variable decl can start with a const
	sToken t1;
	GetToken(&t1);
	if( t1.type == ttConst )
		GetToken(&t1);

	if( !IsDataType(t1.type) )
	{
		RewindTo(&t);
		return false;
	}

	// Object handles can be interleaved with the array brackets
	sToken t2;
	GetToken(&t2);
	while( t2.type == ttHandle || t2.type == ttOpenBracket )
	{
		if( t2.type == ttOpenBracket )
		{
			GetToken(&t2);
			if( t2.type != ttCloseBracket )
			{
				RewindTo(&t);
				return false;
			}
		}

		GetToken(&t2);
	}

	if( t2.type != ttIdentifier )
	{
		RewindTo(&t);
		return false;
	}

	GetToken(&t2);
	if( t2.type == ttEndStatement || t2.type == ttAssignment || t2.type == ttListSeparator )
	{
		RewindTo(&t);
		return true;
	}
	if( t2.type == ttOpenParanthesis ) 
	{	
		// If the closing paranthesis is followed by a statement 
		// block or end-of-file, then treat it as a function. 
		while( t2.type != ttCloseParanthesis && t2.type != ttEnd )
			GetToken(&t2);

		if( t2.type == ttEnd ) 
			return false;
		else
		{
			GetToken(&t1);
			RewindTo(&t);
			if( t1.type == ttStartStatementBlock || t1.type == ttEnd )
				return false;
		}

		RewindTo(&t);

		return true;
	}

	RewindTo(&t);
	return false;
}
Exemplo n.º 8
0
asCScriptNode *asCParser::ParseScript()
{
	asCScriptNode *node = new asCScriptNode(snScript);

	// Determine type of node
	sToken t1;

	for(;;)
	{
		while( !isSyntaxError )
		{
			GetToken(&t1);
			RewindTo(&t1);

			if( t1.type == ttImport )
				node->AddChildLast(ParseImport());
			else if( t1.type == ttClass )
				node->AddChildLast(ParseClass());
			else if( t1.type == ttInterface )
				node->AddChildLast(ParseInterface());
			else if( t1.type == ttConst )
				node->AddChildLast(ParseGlobalVar());
			else if( IsDataType(t1.type) )
			{
				if( IsVarDecl() )
					node->AddChildLast(ParseGlobalVar());
				else
					node->AddChildLast(ParseFunction());
			}
			else if( t1.type == ttEndStatement )
			{
				// Ignore a semicolon by itself
				GetToken(&t1);
			}
			else if( t1.type == ttEnd )
				return node;
			else
			{
				asCString str;
				const char *t = asGetTokenDefinition(t1.type);
				if( t == 0 ) t = "<unknown token>";

				str.Format(TXT_UNEXPECTED_TOKEN_s, t);

				Error(str.AddressOf(), &t1);
			}
		}

		if( isSyntaxError )
		{
			// Search for either ';' or '{' or end
			GetToken(&t1);
			while( t1.type != ttEndStatement && t1.type != ttEnd &&
				   t1.type != ttStartStatementBlock )
				GetToken(&t1);

			if( t1.type == ttStartStatementBlock )
			{
				// Find the end of the block and skip nested blocks
				int level = 1;
				while( level > 0 )
				{
					GetToken(&t1);
					if( t1.type == ttStartStatementBlock ) level++;
					if( t1.type == ttEndStatementBlock ) level--;
					if( t1.type == ttEnd ) break;
				}
			}

			isSyntaxError = false;
		}
	}
	return 0;
}
Exemplo n.º 9
0
	/* 流式的处理特定CLinkerPipe接收到的信息,此函数对于理解本类非常重要,
	s为接收到的字节,或多或少
	*/
	void CLinkerPipe::CompileMsg(const char* s, int32 size)
	{
		
		if(m_RecoType == LINKER_BAN)return;   	
				
		CLinkerPipe::RevContextInfo* Info  = NULL;
		
		if( m_ContextStack.size() > 0 ){ 
			Info = m_ContextStack.front(); //取出之前数据的处理信息
		}
		else{
			Info = new CLinkerPipe::RevContextInfo(&m_CurRevMsg);
			
			m_ContextStack.push_front(Info);
		}
		
		assert(Info != NULL);
		

		bool bCompleteOneData = FALSE;
		
		int i=0;
		while(i<size)
		{				
			char ch = s[i++];
			
			Info->InfoLen++;
			
			//在错误状态下将只关心是否有空管道出现
			//在检测到空管道之前,根据要求,即使是出错的数据也将可能被保存起来,以便分析错误原因
			if(m_bRevError)
			{
				if (Info->Buffer.size() < m_ErrorSaveLen)
				{
					Info->Buffer += ch;
				}
				
				if (ch == '@')
				{
					Info->DataLen ++;
					
					if (Info->DataLen ==ERROR_RESUME_LENGTH)
					{
						EndErrorState(Info);
					}
				}else{
					Info->DataLen =0;
				}
				
				continue;
			}
			
			//正常状态
			switch(Info->State){                                              
			case TYPE_PART:                                                    
				{         
					Info->HeaderStr += ch;
					
					if( IsDataType(ch) && Info->DataType == -1){                   
						Info->DataType = CHAR_TO_TYPE(ch);                                
						if(Info->DataType == TYPE_PIPELINE){                      
							Info->Data = new ePipeline();
							Info->ParentPipe->Push_Directly(Info->Data);

						}                                                          
						//不是PIPELINE但是第一个数据则报错,因为信息的第一个数据类型肯定是TYPE_PIPELINE                       
						else if(Info->ParentPipe == this ){               							
							BeginErrorState(Info,ERROR_TYPE_PART);
						}
						else{ //其他类型则预先生成一个空数据
						
							Info->Data = CreateEmptyData(Info->DataType);
							Info->ParentPipe->Push_Directly(Info->Data);

						}
					}  //确定类型后,改变数据处理状态
					else if(ch == '@' && Info->DataType != -1) 
					{						 
						Info->State = (Info->DataType == TYPE_PIPELINE)?ID_PART : LENGTH_PART;
						Info->Buffer="";
						Info->DataLen = NUMBER_LENGTH_LIMIT;
					}
					else{
						BeginErrorState(Info,ERROR_TYPE_PART);
					}
				}
				break;
			case LENGTH_PART:
				{
					Info->HeaderStr += ch;
					
					// ch ->[0-9] 并且 单个数据长度不能超过10位整数				
					if(isdigit(ch) && Info->Buffer.size() < Info->DataLen)
					{
						Info->Buffer  += ch;
					}
					else if(ch == '@' && Info->Buffer.size() >0)
					{
						Info->DataLen = atol(Info->Buffer.c_str());
						Info->Buffer = "";

						//初步检查长度的合理性
						if(Info->DataType == TYPE_PIPELINE)
						{ 
							if (Info->ParentPipe == this)
							{   

							}

							if(Info->DataLen == 0){
								bCompleteOneData = TRUE;
							}else{

								ePipeline  NotifData;
								NotifData.PushInt(Info->DataLen); //总长度
								NotifData.PushInt(0);             //相对于Parent的完成进度,0则表示本Pipe刚开始
								NotifData.Push_Directly(Info->Data->Clone());
								m_Parent->NotifyLinkerState(this,LINKER_RECEIVE_STEP,NotifData);
								

								//对于管道,得到长度以后即压入堆栈,因为它的数据其实是其它数据的集合								
								Info->HeaderStr="";
								
								ePipeline* Parent = (ePipeline*)Info->Data;
								assert(Parent);
								RevContextInfo* NewInfo = new RevContextInfo(Parent);     
								
								m_ContextStack.push_front(NewInfo);
								Info = NewInfo;
							}

							break;    
						}else	if(Info->DataType == TYPE_NULL)
						{
							if(Info->DataLen != 0){
								BeginErrorState(Info,ERROR_LENGTH_PART);
							}else{
								bCompleteOneData = TRUE;
							}
						}
						else if(Info->DataLen ==0 )
						{ 
							if(Info->DataType == TYPE_STRING){ //允许为0
								bCompleteOneData = TRUE;
							}
							else{//	其他数据不能为0 error
								BeginErrorState(Info,ERROR_LENGTH_PART);
							}
						}else if ((Info->DataType==TYPE_INT || Info->DataType==TYPE_FLOAT) && Info->DataLen>20)
						{
							BeginErrorState(Info,ERROR_LENGTH_PART);
						}
						else{	
							Info->State = DATA_PART;   //一切OK,准备开始处理数据本身
						}
					}
					else{
						BeginErrorState(Info,ERROR_LENGTH_PART);
					}
				}
				break;
				
			case DATA_PART:
				{
					Info->Buffer += ch;
					
					if( Info->Buffer.size() == Info->DataLen ){
						
						Info->HeaderStr+=Info->Buffer;							
						int32 n = Info->Data->FromString(Info->HeaderStr,0);
						assert(n!=0);
						
						bCompleteOneData = TRUE;

					}
				}
				break;
			case ID_PART:
				{		
					//	Info->HeaderStr += ch;
					
					// ch ->[0-9] 并且数据ID不能超过20位整数				
					if(isdigit(ch) && Info->Buffer.size() < Info->DataLen)
					{
						Info->Buffer += ch;
					}
					else if(ch == '@' && Info->Buffer.size() >0)
					{
						int64 ID = atoint64(Info->Buffer.c_str());
						
						assert(Info->DataType == TYPE_PIPELINE);
						ePipeline* Data = (ePipeline*)Info->Data;
						Data->SetID(ID); 
						
						Info->State = NAMELEN_PART;
						Info->Buffer = "";
						Info->DataLen = DATA_LENGTH_LIMIT;
					}
					else{
						BeginErrorState(Info,ERROR_ID_PART);						
					}
				}
				break;
			case NAMELEN_PART:
				{
					//	Info->HeaderStr += ch;
					
					// ch ->[0-9] 并且 不能超过10位整数				
					if(isdigit(ch) && Info->Buffer.size() < Info->DataLen)
					{
						Info->Buffer += ch;
					}
					else if(ch == '@' && Info->Buffer.size() >0)
					{
						uint32 len = atol(Info->Buffer.c_str());
						
						Info->DataLen = len; 
						Info->Buffer = "";
						assert(Info->Buffer.size()==0);
						Info->State = NAME_PART;
					}
					else{
						BeginErrorState(Info,ERROR_NAMELEN_PART);		
					}
				}
				break;
			case NAME_PART:
				{
					//	Info->HeaderStr += ch;
					
					// ch ->[0-9] 并且 不能超过约定位数				
					if(Info->Buffer.size() < Info->DataLen)
					{
						Info->Buffer += ch;
					}
					else if(ch == '@'){
						eSTRING s;
						s.FromString(Info->Buffer,0);
						tstring Name = s;

						assert(Info->DataType == TYPE_PIPELINE);
						ePipeline* Data = (ePipeline*)Info->Data;
						Data->SetLabel(Name.c_str()); 
						
						Info->Buffer = "";
						Info->State = LENGTH_PART;
						Info->DataLen = DATA_LENGTH_LIMIT;
					}
					else{
						BeginErrorState(Info,ERROR_NAME_PART);
					}
				}
				break;
			default:
				assert(0);
				break;
				
			}
			
			if(bCompleteOneData){
				bCompleteOneData = FALSE;
				
				//处理得到的实际数据
				while(m_ContextStack.size()){	
					
					//Info->ParentPipe->Push_Directly(Info->Data);
					
					int32 Len = Info->InfoLen;
		            Energy* Data = Info->Data;
					
					if (m_ContextStack.size()>1)
					{
						RevContextInfo* PreInfo = m_ContextStack[1];
						
						PreInfo->InfoLen += Len;
						
						PreInfo->DataLen -= Len;
						
						if (PreInfo->DataLen  == 0) //已经完成一个嵌套Pipe,重复上述步骤
						{
						
							ePipeline  NotifData;
							NotifData.PushInt(Len);   //总长度								
							NotifData.PushInt(PreInfo->InfoLen); //Parent Pipe已经完成的
							NotifData.Push_Directly(Data->Clone());								
							m_Parent->NotifyLinkerState(this,LINKER_RECEIVE_STEP,NotifData);
															
							delete Info;
							m_ContextStack.pop_front();
							Info = m_ContextStack.front();
							
							assert(PreInfo == Info);	

						}else if (PreInfo->DataLen > 0) //继续接收下一个数据
						{
							Info->Reset();  
							break;
						}else{ //错误
							BeginErrorState(Info,ERROR_OTHER_PARNT);
							Info->Reset();
						}
					}else{ //已经完成一个完整信息的组装
						
						assert(m_ContextStack.size()==1);
						assert(m_CurRevMsg.Size()==1);

						eElectron E;
						m_CurRevMsg.Pop(&E);
						
					
						RevOneMsg(E);

						assert(Info->ParentPipe == &m_CurRevMsg);
						Info->Reset();
						break;
					}
				}//while
			}
      }//while
}
Exemplo n.º 10
0
HCC_TOKEN* icode_generator::getToken(void)
{
	check_bounds(0);
	HCC_TOKEN* token_ptr = new HCC_TOKEN;
	//do loop to extract the line markers	
	HCC_TOKEN_TYPE token_type = HCC_TOKEN_ERROR;

	do{
		memcpy((void*)&token_type, cursor, sizeof(wchar_t));		
		cursor += sizeof(wchar_t);

		if(token_type==HCC_LINE_MARKER){			
			memcpy(&line_number, cursor, sizeof(int));
			cursor += sizeof(int);
		}
	}while(token_type==HCC_LINE_MARKER || IsDataType(token_type) || IsStorageSpec(token_type));
	//
	token_ptr->tokenType = token_type;
	switch(token_type)
	{
	case HCC_NUMBER:
	case HCC_STRING_LITERAL:
	case HCC_CHARACTER:
	case HCC_CONTROL_CHAR:

	case HCC_IDENTIFIER:
	case HCC_SIZEOF:
	
	case HCC_TRUE:
	case HCC_FALSE:
	case HCC_NULL:
		{			
			symbol_ptr = get_symbol();
			_tcsncpy(token_ptr->token, symbol_ptr->String().c_str(),
						symbol_ptr->String().length());
			token_ptr->token[symbol_ptr->String().length()] = _T('\0');
			token_ptr->dataType = symbol_ptr->getDataType();
			//must set the data type for the internal representation of data
			//and for correct evaluation by the H++ interpreter...
			switch(token_type)
			{
			case HCC_NUMBER:
				{
				if(symbol_ptr->getDataType()==HCC_INTEGER)
					token_ptr->value.Integer = symbol_ptr->getDeclDefinition().constant.value.Integer; // (int)symbol_ptr->getValue();
				else if(symbol_ptr->getDataType()==HCC_FLOATING_POINT)
					token_ptr->value.Double = symbol_ptr->getDeclDefinition().constant.value.Double; //symbol_ptr->getValue();
				}
				break;
			case HCC_CHARACTER:
			case HCC_CONTROL_CHAR:
				token_ptr->value.Character = symbol_ptr->getDeclDefinition().constant.value.Character;
				break;
			case HCC_BOOLEAN:
				token_ptr->value.Boolean = symbol_ptr->getDeclDefinition().constant.value.Boolean;
				break;
			default:
				//for all other types...
				token_ptr->value.Integer = symbol_ptr->getDeclDefinition().constant.value.Integer; 
				break;
			}

		}
		break;
	default:
		{
			symbol_ptr = NULL;
			if(token_type>HCC_LINE_MARKER && token_type<=HCC_WITH)
				_tcscpy(token_ptr->token, symbolStrings[token_type]);			
			else if(token_type < HCC_TOKEN_ERROR || token_type > HCC_WITH)
				token_ptr->tokenType = HCC_EOF;
			
		}
		break;
	};
	return token_ptr;
}