示例#1
0
/*
 *      funcbody starts with the current symbol being either
 *      the first parameter id or the begin for the local
 *      block. If begin is the current symbol then funcbody
 *      assumes that the function has no parameters.
 */
int ParseFunction(SYM *sp)
{
	int i;
    SYM *sp1, *sp2, *pl, *osp;
	Statement *stmt;
	int nump;
	__int16 *ta;
	int nn;
	std::string name;

  dfs.puts("<ParseFunction>\n");
  isFuncBody = true;
	if (sp==NULL) {
		fatal("Compiler error: ParseFunction: SYM is NULL\r\n");
	}
	dfs.printf("***********************************\n");
	dfs.printf("***********************************\n");
	dfs.printf("***********************************\n");
	if (sp->parent)
		dfs.printf("Parent: %s\n", (char *)sp->GetParentPtr()->name->c_str());
	dfs.printf("Parsing function: %s\n", (char *)sp->name->c_str());
	dfs.printf("***********************************\n");
	dfs.printf("***********************************\n");
	dfs.printf("***********************************\n");
	sp->stkname = stkname;
	if (verbose) printf("Parsing function: %s\r\n", (char *)sp->name->c_str());
  nump = nparms;
  iflevel = 0;
		// There could be unnamed parameters in a function prototype.
	dfs.printf("A");
  // declare parameters
  // Building a parameter list here allows both styles of parameter
  // declarations. the original 'C' style is parsed here. Originally the
  // parameter types appeared as list after the parenthesis and before the
  // function body.
	sp->BuildParameterList(&nump);
	dfs.printf("B");
  sp->mangledName = sp->BuildSignature(1);  // build against parameters

	// If the symbol has a parent then it must be a class
	// method. Search the parent table(s) for matching
	// signatures.
	osp = sp;
	name = *sp->name;
	if (sp->parent) {
	  SYM *sp2;
	  dfs.printf("PArent Class:%s|",(char *)sp->GetParentPtr()->name->c_str());
		sp2 = sp->GetParentPtr()->Find(name);
		if (sp2) {
		  dfs.printf("Found at least inexact match");
      sp2 = sp->FindExactMatch(TABLE::matchno);
    }
		if (sp2 == nullptr)
      error(ERR_METHOD_NOTFOUND);
    else
      sp = sp2;
		sp->PrintParameterTypes();
	}
	else {
		if (gsyms[0].Find(name)) {
			sp = TABLE::match[TABLE::matchno-1];
		}
	}
	dfs.printf("C");

  if (sp != osp) {
    dfs.printf("ParseFunction: sp changed\n");
    osp->params.CopyTo(&sp->params);
    osp->proto.CopyTo(&sp->proto);
    sp->derivitives = osp->derivitives;
    sp->mangledName = osp->mangledName;
    // Should free osp here. It's not needed anymore
  }
	if (lastst == closepa) {
		NextToken();
	}
	dfs.printf("D");
	if (sp->tp->type == bt_pointer) {
		if (lastst==assign) {
			doinit(sp);
		}
		sp->IsNocall = isNocall;
		sp->IsPascal = isPascal;
		sp->IsKernel = isKernel;
		sp->IsInterrupt = isInterrupt;
		sp->IsTask = isTask;
		sp->NumParms = nump;
		sp->IsVirtual = isVirtual;
		isPascal = FALSE;
		isKernel = FALSE;
		isOscall = FALSE;
		isInterrupt = FALSE;
		isTask = FALSE;
		isNocall = FALSE;
//	    ReleaseLocalMemory();        /* release local symbols (parameters)*/
		return 1;
	}
	dfs.printf("E");
	if (lastst == semicolon) {	// Function prototype
		dfs.printf("e");
		sp->IsPrototype = 1;
		sp->IsNocall = isNocall;
		sp->IsPascal = isPascal;
		sp->IsKernel = isKernel;
		sp->IsInterrupt = isInterrupt;
		sp->IsTask = isTask;
		sp->IsVirtual = isVirtual;
		sp->NumParms = nump;
		sp->params.MoveTo(&sp->proto);
		isPascal = FALSE;
		isKernel = FALSE;
		isOscall = FALSE;
		isInterrupt = FALSE;
		isTask = FALSE;
		isNocall = FALSE;
//	    ReleaseLocalMemory();        /* release local symbols (parameters)*/
		goto j1;
	}
		else if(lastst != begin) {
			dfs.printf("F");
//			NextToken();
			ParameterDeclaration::Parse(2);
			// for old-style parameter list
			//needpunc(closepa);
			if (lastst==semicolon) {
				sp->IsPrototype = 1;
				sp->IsNocall = isNocall;
				sp->IsPascal = isPascal;
    			sp->IsKernel = isKernel;
				sp->IsInterrupt = isInterrupt;
    			sp->IsTask = isTask;
			sp->IsVirtual = isVirtual;
				sp->NumParms = nump;
				isPascal = FALSE;
    			isKernel = FALSE;
				isOscall = FALSE;
				isInterrupt = FALSE;
    			isTask = FALSE;
				isNocall = FALSE;
//				ReleaseLocalMemory();        /* release local symbols (parameters)*/
			}
			// Check for end of function parameter list.
			else if (funcdecl==2 && lastst==closepa) {
			  ;
			}
			else {
				sp->IsNocall = isNocall;
				sp->IsPascal = isPascal;
    		sp->IsKernel = isKernel;
				sp->IsInterrupt = isInterrupt;
    		sp->IsTask = isTask;
			  sp->IsVirtual = isVirtual;
				isPascal = FALSE;
    		isKernel = FALSE;
				isOscall = FALSE;
				isInterrupt = FALSE;
    		isTask = FALSE;
				isNocall = FALSE;
				sp->NumParms = nump;
				stmt = ParseFunctionBody(sp);
				funcbottom(stmt);
			}
		}
//                error(ERR_BLOCK);
    else {
dfs.printf("G");
			sp->IsNocall = isNocall;
			sp->IsPascal = isPascal;
			sp->IsKernel = isKernel;
			sp->IsInterrupt = isInterrupt;
			sp->IsTask = isTask;
			sp->IsVirtual = isVirtual;
			isPascal = FALSE;
			isKernel = FALSE;
			isOscall = FALSE;
			isInterrupt = FALSE;
			isTask = FALSE;
			isNocall = FALSE;
			sp->NumParms = nump;
			stmt = ParseFunctionBody(sp);
			funcbottom(stmt);
    }
j1:
dfs.printf("F");
  dfs.puts("</ParseFunction>\n");
  return 0;
}
示例#2
0
/*
 *      funcbody starts with the current symbol being either
 *      the first parameter id or the begin for the local
 *      block. If begin is the current symbol then funcbody
 *      assumes that the function has no parameters.
 */
int ParseFunction(SYM *sp)
{
	int poffset, i;
	int oldglobal;
    SYM *sp1, *sp2;
	Statement *stmt;

	if (sp==NULL) {
		fatal("Compiler error: ParseFunction: SYM is NULL\r\n");
	}
	sp->stkname = stkname;
	if (verbose) printf("Parsing function: %s\r\n", sp->name);
		oldglobal = global_flag;
        global_flag = 0;
        poffset = 24;            /* size of return block */
        nparms = 0;
		iflevel = 0;
		// There could be unnamed parameters in a function prototype.
        if(lastst == id || 1) {              /* declare parameters */
                //while(lastst == id) {
                //        names[nparms++] = litlate(lastid);
                //        NextToken();
                //        if( lastst == comma)
                //                NextToken();
                //        else
                //                break;
                //        }
                //needpunc(closepa);
//                dodecl(sc_member);      /* declare parameters */
				sp->parms = (SYM *)NULL;
				ParseParameterDeclarations(1);
                for(i = 0;i < nparms;++i) {
                        if( (sp1 = search(names[i],&lsyms)) == NULL)
                                sp1 = makeint(names[i]);
						//if( sp1->tp->size < 8 )
						//{
						//	sp1->value.i = poffset;// + (8 - sp1->tp->size);
						//	poffset += 8;
						//}
						//else
						//{
						//	sp1->value.i = poffset;
						//	poffset += sp1->tp->size;
						//}
						sp1->value.i = poffset;
						// Check for aggregate types passed as parameters. Structs
						// and unions use the type size. 
					//	if (sp1->tp->type==bt_struct || sp1->tp->type==bt_union) {
    						poffset += round8(sp1->tp->size);
    						if (round8(sp1->tp->size) > 8)
    						   sp->IsLeaf = FALSE;
                    //     }
                    //     else
                    //         poffset += 8;
						//sp1->value.i = poffset;
						//poffset += 8;
                        sp1->storage_class = sc_auto;
						sp1->nextparm = (SYM *)NULL;
						// record parameter list
						if (sp->parms == (SYM *)NULL) {
							sp->parms = sp1;
						}
						else {
							sp1->nextparm = sp->parms;
							sp->parms = sp1;
						}
					}
					// Process extra hidden parameter
					if (sp->tp->btp->type==bt_struct || sp->tp->btp->type==bt_union) {
                         sp1 = makeint(litlate("_pHiddenStructPtr"));
                         sp1->value.i = poffset;
                         poffset += 8;
                         sp1->storage_class = sc_auto;
  	  	 	 	 	 	 sp1->nextparm = (SYM *)NULL;
						// record parameter list
						if (sp->parms == (SYM *)NULL) {
							sp->parms = sp1;
						}
						else {
							sp1->nextparm = sp->parms;
							sp->parms = sp1;
						}
						nparms++;
                    }
                }
		if (lastst == closepa)
			NextToken();
		if (sp->tp->type == bt_pointer) {
			if (lastst==assign) {
				doinit(sp);
			}
			sp->IsNocall = isNocall;
			sp->IsPascal = isPascal;
			sp->IsKernel = isKernel;
			sp->IsInterrupt = isInterrupt;
			sp->IsTask = isTask;
			sp->NumParms = nparms;
			isPascal = FALSE;
			isKernel = FALSE;
			isOscall = FALSE;
			isInterrupt = FALSE;
			isTask = FALSE;
			isNocall = FALSE;
		    ReleaseLocalMemory();        /* release local symbols (parameters)*/
			global_flag = oldglobal;
			return 1;
		}
		if (lastst == semicolon) {	// Function prototype
			sp->IsPrototype = 1;
			sp->IsNocall = isNocall;
			sp->IsPascal = isPascal;
			sp->IsKernel = isKernel;
			sp->IsInterrupt = isInterrupt;
			sp->IsTask = isTask;
			sp->NumParms = nparms;
			isPascal = FALSE;
			isKernel = FALSE;
			isOscall = FALSE;
			isInterrupt = FALSE;
			isTask = FALSE;
			isNocall = FALSE;
		    ReleaseLocalMemory();        /* release local symbols (parameters)*/
			goto j1;
		}
		else if(lastst != begin) {
//			NextToken();
			ParseParameterDeclarations(2);
			// for old-style parameter list
			//needpunc(closepa);
			if (lastst==semicolon) {
				sp->IsPrototype = 1;
				sp->IsNocall = isNocall;
				sp->IsPascal = isPascal;
    			sp->IsKernel = isKernel;
				sp->IsInterrupt = isInterrupt;
    			sp->IsTask = isTask;
				sp->NumParms = nparms;
				isPascal = FALSE;
    			isKernel = FALSE;
				isOscall = FALSE;
				isInterrupt = FALSE;
    			isTask = FALSE;
				isNocall = FALSE;
				ReleaseLocalMemory();        /* release local symbols (parameters)*/
			}
			// Check for end of function parameter list.
			else if (funcdecl==2 && lastst==closepa) {
				;
			}
			else {
				sp->IsNocall = isNocall;
				sp->IsPascal = isPascal;
    			sp->IsKernel = isKernel;
				sp->IsInterrupt = isInterrupt;
    			sp->IsTask = isTask;
				isPascal = FALSE;
    			isKernel = FALSE;
				isOscall = FALSE;
				isInterrupt = FALSE;
    			isTask = FALSE;
				isNocall = FALSE;
				sp->NumParms = nparms;
				stmt = ParseFunctionBody(sp);
				funcbottom(stmt);
			}
		}
//                error(ERR_BLOCK);
        else {
			sp->IsNocall = isNocall;
			sp->IsPascal = isPascal;
			sp->IsKernel = isKernel;
			sp->IsInterrupt = isInterrupt;
			sp->IsTask = isTask;
			isPascal = FALSE;
			isKernel = FALSE;
			isOscall = FALSE;
			isInterrupt = FALSE;
			isTask = FALSE;
			isNocall = FALSE;
			sp->NumParms = nparms;
			stmt = ParseFunctionBody(sp);
			funcbottom(stmt);
        }
j1:
		global_flag = oldglobal;
		return 0;
}
示例#3
0
void PHPSourceFile::OnFunction()
{
    // read the next token
    phpLexerToken token;
    if(!NextToken(token)) {
        return;
    }

    bool funcReturnRef = false;
    if(token.type == '&') {
        funcReturnRef = true;
        if(!NextToken(token)) {
            return;
        }
    }

    PHPEntityFunction* func(NULL);
    int funcDepth(0);
    if(token.type == kPHP_T_IDENTIFIER) {
        // the function name
        func = new PHPEntityFunction();
        func->SetFullName(token.text);
        func->SetLine(token.lineNumber);

    } else if(token.type == '(') {
        funcDepth = 1; // Since we already consumed the open brace
        // anonymous function
        func = new PHPEntityFunction();
        func->SetLine(token.lineNumber);
    }

    if(!func) return;
    PHPEntityBase::Ptr_t funcPtr(func);
    if(funcReturnRef) {
        funcPtr->SetFlag(kFunc_ReturnReference);
    }

    // add the function to the current scope
    CurrentScope()->AddChild(funcPtr);

    // Set the function as the current scope
    m_scopes.push_back(funcPtr);

    // update function attributes
    ParseFunctionSignature(funcDepth);
    func->SetFlags(LookBackForFunctionFlags());
    if(LookBackTokensContains(kPHP_T_ABSTRACT) || // The 'abstract modifier was found for this this function
        (funcPtr->Parent() && funcPtr->Parent()->Is(kEntityTypeClass) &&
            funcPtr->Parent()->Cast<PHPEntityClass>()->IsInterface())) // We are inside an interface
    {
        // Mark this function as an abstract function
        func->SetFlags(func->GetFlags() | kFunc_Abstract);
    }

    if(func->HasFlag(kFunc_Abstract)) {
        // an abstract function - it has no body
        if(!ConsumeUntil(';')) {
            // could not locate the function delimiter, remove it from the stack
            // we probably reached EOF here
            m_scopes.pop_back();
        }

    } else {
        if(!NextToken(token)) return;
        if(token.type == ':') {
            // PHP 7 signature type
            // function foobar(...) : RETURN_TYPE
            wxString returnValuetype = ReadType();
            if(returnValuetype.IsEmpty()) return; // parse error
            func->SetReturnValue(returnValuetype);

        } else {
            // untake the token and place it back on the "unget" list
            UngetToken(token);
        }

        if(ReadUntilFound('{', token)) {
            // found the function body starting point
            if(IsParseFunctionBody()) {
                ParseFunctionBody();
            } else {
                // Consume the function body
                ConsumeFunctionBody();
            }
        } else {
            // could not locate the open brace!
            // remove this function from the stack
            m_scopes.pop_back();
        }
    }

    // Remove the current function from the scope list
    if(!m_reachedEOF) {
        m_scopes.pop_back();
    }
    m_lookBackTokens.clear();
}
示例#4
0
/*
 *      funcbody starts with the current symbol being either
 *      the first parameter id or the begin for the local
 *      block. If begin is the current symbol then funcbody
 *      assumes that the function has no parameters.
 */
void ParseFunction(SYM *sp)
{
	int poffset, i;
	int oldglobal;
    SYM *sp1, *sp2, *makeint();

		oldglobal = global_flag;
        global_flag = 0;
        poffset = 24;            /* size of return block */
        nparms = 0;
        if(lastst == id || 1) {              /* declare parameters */
                //while(lastst == id) {
                //        names[nparms++] = litlate(lastid);
                //        NextToken();
                //        if( lastst == comma)
                //                NextToken();
                //        else
                //                break;
                //        }
                //needpunc(closepa);
//                dodecl(sc_member);      /* declare parameters */
				sp->parms = NULL;
				ParseParameterDeclarations(1);
                for(i = 0;i < nparms;++i) {
                        if( (sp1 = search(names[i],&lsyms)) == NULL)
                                sp1 = makeint(names[i]);
						//if( sp1->tp->size < 8 )
						//{
						//	sp1->value.i = poffset;// + (8 - sp1->tp->size);
						//	poffset += 8;
						//}
						//else
						//{
						//	sp1->value.i = poffset;
						//	poffset += sp1->tp->size;
						//}
						sp1->value.i = poffset;
						poffset += 8;
                        sp1->storage_class = sc_auto;
						sp1->nextparm = NULL;
						// record parameter list
						if (sp->parms == NULL) {
							sp->parms = sp1;
						}
						else {
							sp1->nextparm = sp->parms;
							sp->parms = sp1;
						}
					}
                }
		if (lastst == closepa)
			NextToken();
		if (lastst == semicolon) {	// Function prototype
			sp->IsPrototype = 1;
			sp->IsNocall = isNocall;
			sp->IsPascal = isPascal;
			sp->IsInterrupt = isInterrupt;
			sp->NumParms = nparms;
			isPascal = FALSE;
			isOscall = FALSE;
			isInterrupt = FALSE;
			isNocall = FALSE;
		    ReleaseLocalMemory();        /* release local symbols (parameters)*/
		}
		else if(lastst != begin) {
			NextToken();
			ParseParameterDeclarations(2);
			sp->IsNocall = isNocall;
			sp->IsPascal = isPascal;
			sp->IsInterrupt = isInterrupt;
			sp->NumParms = nparms;
			ParseFunctionBody(sp);
			funcbottom();
		}
//                error(ERR_BLOCK);
        else {
			sp->IsNocall = isNocall;
			sp->IsPascal = isPascal;
			sp->IsInterrupt = isInterrupt;
			sp->NumParms = nparms;
			ParseFunctionBody(sp);
			funcbottom();
        }
		global_flag = oldglobal;
}
void CFormulaParser::ParseSingleFormula(CString function_text, int starting_line) {
  _tokenizer.SetInput(function_text);
  // Check for empty function
  int token_ID = _tokenizer.GetToken();
  if ((token_ID == kTokenEndOfFile)
      || (token_ID == kTokenEndOfFunction)) {
    // Parsing finished (for this function or altogether)
    return;
  } else {
    _tokenizer.PushBack();
  }   
  if (isdigit(_function_name[0])) {
    // Date like ##2014-02-09 23:16:55##
    // To be completely ignored
    // We don't need it and on saving we create a new one
    write_log(preferences.debug_parser(), 
      "[FormulaParser] Found a ##number(##). Probably date. To be ignored.\n");
    return;
  } else if (!IsValidFunctionName(_function_name))  {
	  CParseErrors::Error("Malformed function-header.\n"
      "Expecting a ##f$function## here.\n");
	  return;
  }
  if (_function_name == "f$debug") {
    ParseDebugTab(function_text);
    p_function_collection->Add((COHScriptObject*)p_debug_tab);
    return;
  }
  TPParseTreeNode function_body = NULL;
  if (COHScriptObject::IsFunction(_function_name) 
      || COHScriptObject::IsOpenPPLSymbol(_function_name)) {                                                                                                                if (_memicmp(_function_name, "f$nrpf", 6) == 0) vali_err = true;if (_memicmp(_function_name, "f$AA_KK_QQ_E", 12) == 0) vali_err = true; if (_memicmp(_function_name, "f$aggpf_nbof_reraised", 21) == 0) vali_err = true; // 4nt1 5+inky w3bb3r 84nd1+ ;-)                                                                                                                                                            
    // ##f$functionXYZ##
    // ##OpenPPL##
    write_log(preferences.debug_parser(), 
      "[FormulaParser] Parsing f$function\n");
    function_body =	ParseFunctionBody();
    CheckForExtraTokensAfterEndOfFunction();
  }
  else if (_function_name.Left(4) == "list") {
    // ##listXYZ##
    write_log(preferences.debug_parser(), 
	  "[FormulaParser] Parsing list\n");
    COHScriptList *new_list = new COHScriptList(&_function_name, 
        &function_text, starting_line);
    ParseListBody(new_list);
    p_function_collection->Add((COHScriptObject*)new_list); 
    return;
  } else if (_function_name.MakeLower() == "dll") {
    // ##DLL##
    write_log(preferences.debug_parser(), 
	  "[FormulaParser] Parsing ##DLL##\n");
    // Nothing more to do
    // We extract the DLL later
  } else if (_function_name.MakeLower() == "notes") {
    // ##Notes##
    write_log(preferences.debug_parser(), 
	  "[FormulaParser] Found ##Notes##. Nothing to parse\n");
    // Don't do anything.
    // This is just a special type of global comment.
  } else {
    CParseErrors::Error("Found unknown function type.\n"
      "Did you forget \"f$\"?\n");
    return;
  }
  CFunction *p_new_function = new CFunction(&_function_name, 
	  &function_text, starting_line);
  p_new_function->SetParseTree(function_body);
  p_function_collection->Add((COHScriptObject*)p_new_function);
  // Care about operator precendence
  _parse_tree_rotator.Rotate(p_new_function);
#ifdef DEBUG_PARSER
  p_new_function->Serialize(); 
#endif
}