Ejemplo n.º 1
0
Parameter* FunctionDef::parseNextParam( Tokenizer& tok, bool isFuncName )
{
   FormingParam::state state;
   Parameter *ret = 0;

   state.nextState = &FP_start;

   while( tok.hasCurrent() )
   {
      String next = tok.getToken();
      ret = state.nextState->parseNext( next, state );

      if ( state.m_forming != 0 )
      {
         // ok, we should parse the parameter list of this parameter.
         if( tok.next() )
         {
            // this is to skip the initial "(".
            if ( tok.getToken() != "(" || ! tok.next() )
               tpe( __LINE__ );

            parseFuncParams( state.m_forming->m_funcParams, tok );
         }
      }
      else if ( ret != 0 )
      {
         return ret;
      }

      tok.next();
      if( isFuncName && tok.getToken() == "(" )
      {
         return state.makeParameter();
      }
   }

   return ret;
}
Ejemplo n.º 2
0
static PSmmAstNode parseFactor(PSmmParser parser) {
	PSmmAstNode res = &errorNode;
	bool canBeFuncDefn = parser->prevToken && parser->prevToken->kind == ':';
	PSmmToken unary = getUnaryOperator(parser);
	canBeFuncDefn = canBeFuncDefn && !unary;
	if (parser->curToken->kind == '(') {
		getNextToken(parser);
		if (parser->curToken->kind == ')') {
			getNextToken(parser);
			if (canBeFuncDefn) {
				PSmmAstNode param = smmNewAstNode(nkSmmParamDefinition, parser->a);
				param->asParam.count = 0;
				return param;
			}
			smmPostMessage(parser->msgs, errSmmGotUnexpectedToken, parser->curToken->filePos, "expression", "')'");
			findToken(parser, ';');
			return &errorNode;
		}
		parser->curToken->canBeNewSymbol = canBeFuncDefn;
		res = parseExpression(parser);
		if (res == &errorNode) {
			if (findToken(parser, ')')) getNextToken(parser);
			return &errorNode;
		}
		// In case expression is followed by ':' it must be just ident and thus first param of func declaration
		if (parser->curToken->kind == ':') {
			assert(canBeFuncDefn && res->isIdent);
			res = parseFuncParams(parser, &res->asParam);
		}
		if (!expect(parser, ')')) {
			int tk = parser->curToken->kind;
			PSmmAstNode param = res;
			switch (res->kind) {
			case nkSmmParamDefinition:
				while (param) {
					ibsDictPop(parser->idents, param->token->repr);
					param = param->next;
				}
				// If it seems only ')' was forgotten in func definition we want to coninue parsing.
				// Otherwise we want to fallthrough to error handling.
				if (tk == tkSmmRArrow || tk == '{' || tk == ';') break;
			default:
				if (findToken(parser, ')')) getNextToken(parser);
				return &errorNode;
			}
		}
	} else {
		switch (parser->curToken->kind) {
		case tkSmmIdent: res = parseIdentFactor(parser); break;
		case tkSmmUInt: case tkSmmInt: case tkSmmFloat: case tkSmmBool:
			res = getLiteralNode(parser);
			break;
		default:
			if (parser->curToken->kind != tkSmmErr) {
				char gotBuf[4];
				const char* got = smmTokenToString(parser->curToken, gotBuf);
				smmPostMessage(parser->msgs, errSmmGotUnexpectedToken, parser->curToken->filePos, "identifier or literal", got);
			}
			break;
		}
	}

	if (res == &errorNode || !unary) return res;

	switch (unary->kind) {
	case '-':
		if (res->kind == nkSmmInt || res->kind == nkSmmFloat) {
			assert(false && "Lexer should have handled this case!");
		} else {
			PSmmAstNode neg = smmNewAstNode(nkSmmNeg, parser->a);
			neg->left = res;
			neg->token = unary;
			res = neg;
		}
		break;
	case tkSmmNot:
		{
			PSmmAstNode not = smmNewAstNode(nkSmmNot, parser->a);
			not->left = res;
			not->type = &builtInTypes[tiSmmBool];
			not->token = unary;
			res = not;
			break;
		}
	}
	return res;
}