//==========================================================================
//
// DoActionSpecials
// handles action specials as code pointers
//
//==========================================================================
bool DoActionSpecials(FState & state, bool multistate, int * statecount, Baggage &bag)
{
	int i;
	const ACSspecials *spec;

	if ((spec = is_special (sc_String, sc_StringLen)) != NULL)
	{

		int paramindex=PrepareStateParameters(&state, 6);

		StateParameters[paramindex]=spec->Special;

		// Make this consistent with all other parameter parsing
		if (SC_CheckToken('('))
		{
			for (i = 0; i < 5;)
			{
				StateParameters[paramindex+i+1]=ParseExpression (false, bag.Info->Class);
				i++;
				if (!SC_CheckToken (',')) break;
			}
			SC_MustGetToken (')');
		}
		else i=0;

		if (i < spec->MinArgs)
		{
			SC_ScriptError ("Too few arguments to %s", spec->name);
		}
		if (i > MAX (spec->MinArgs, spec->MaxArgs))
		{
			SC_ScriptError ("Too many arguments to %s", spec->name);
		}
		state.Action = A_CallSpecial;
		return true;
	}
	return false;
}
Sentencia* Sintactico::ParseAssignmentStatement(string nombre_id)
{
		list<Qualifier*> qualifier_list = ParseQualifiers();

		if ( proximo_token.GetTipo() == op_asignacion )
		{
			proximo_token = analizador_lexico->ObtenerSiguienteToken();

			Expresion* expr = ParseExpression();

			if ( proximo_token.GetTipo() == punt_puntocoma )
				proximo_token = analizador_lexico->ObtenerSiguienteToken();
			else
				throw SyntaxException("Falta un punto y coma",analizador_lexico->GetLineaActual());

			Identificador* identificador = new Identificador(nombre_id,qualifier_list);

			return new SentenciaAsignacion(identificador,expr);
		}
		else
			throw SyntaxException("no se encontro el operador de asignacion",analizador_lexico->GetLineaActual());
	
}
Example #3
0
// Parser high-level token
void SqlParser::Parse(Token *token, int scope, int *result_sets)
{
	bool exists = false;

	// If application scope is set, start from an application statement
	if(_source_app != 0)
	{
		_level = LEVEL_APP;

		if(_source_app == APP_COBOL && _cobol != NULL)
			exists = _cobol->ParseStatement(token);

		_level = LEVEL_SQL;
	}

	if(exists == true)
		return;

	if(ParseStatement(token, scope, result_sets) == true)
		return;

	if(ParseSystemProcedure(NULL, token) == true)
		return;

	exists = ParseExpression(token);

	// Standalone function call
	if(exists == true && token->type == TOKEN_FUNCTION && token->t_type != TOKEN_STATEMENT && 
		scope == SQL_SCOPE_PROC)
	{
		// Netezza requires explicit CALL keyword
		if(_target == SQL_NETEZZA)
		{
			Prepend(token, "CALL ", L"CALL ", 5);
		}
	}
}
Example #4
0
TExpressionPtr ExpressionParser::ParseParameterizedVariableExpression(StringPtrLen str) const
{
   BracketsContent content;
   auto name = content.Parse(str);
   if (str.Len() == name.Len())
   {
      return TExpressionPtr();
   }

   name.Trim();
   CheckQualifier(name, "Variable name");

   auto variable = m_variable_mgr.FindVariable(name);
   if (nullptr == variable)
   {
      Error("Usage of undefined variable '", name, "'.");
   }

   TExpressionPtrVector actual_params;
   actual_params.reserve(5);

   StringPtrLen param;
   while (content.GetPart(param))
   {
      auto param_expr = ParseExpression(param);
      actual_params.push_back(std::move(param_expr));
   }

   if (actual_params.size() != variable->GetParameterCount())
   {
      Error("Incorrect amount of parameters during usage of variable '", variable->GetName(), 
         "'. Expected amount - ", variable->GetParameterCount(), ", actual amount - ", actual_params.size(), ".");
   }

   return variable->GetExpression()->CloneWithSubstitution(actual_params);
}
nsresult nsAbQueryStringToExpression::Convert (
    const nsACString &aQueryString,
    nsIAbBooleanExpression** expression)
{
    nsresult rv;

    nsCAutoString q(aQueryString);
    q.StripWhitespace();
    const char *queryChars = q.get();

    nsCOMPtr<nsISupports> s;
    rv = ParseExpression(&queryChars, getter_AddRefs(s));
    NS_ENSURE_SUCCESS(rv, rv);

    // Case: Not end of string
    if (*queryChars != 0)
        return NS_ERROR_FAILURE;

    nsCOMPtr<nsIAbBooleanExpression> e(do_QueryInterface(s, &rv));
    NS_ENSURE_SUCCESS(rv, rv);

    NS_IF_ADDREF(*expression = e);
    return rv;
}
void CFormulaParser::ParseDebugTab(CString function_text) {
  p_debug_tab->Clear();
  CString next_line;
  int separator_index = 0;
  // Split lines
  while (AfxExtractSubString(next_line, function_text, separator_index, '\n')) {
    ++separator_index;
    int pos = next_line.Find('=');
    if (pos < 0) {
      // No equality-sign found. Empty line or not valid
      continue;
    }
    // Expression-text: everything behind first "="
    int expresion_length = next_line.GetLength() - pos - 1;
    CString expression_text = next_line.Right(expresion_length);
    // Parse this line
    _tokenizer.SetInput(expression_text);
    TPParseTreeNode expression = ParseExpression();
    // Care about operator precendence
    _parse_tree_rotator.Rotate(expression, &expression);
    // Add line and expression to debug-tab
    p_debug_tab->AddExpression(expression_text, expression);
  }
}
Example #7
0
File: expr.c Project: M-ike/work
/**
 *  postfix-expression:
 *		primary-expression
 *		postfix-expression [ expression ]
 *		postfix-expression ( [argument-expression-list] )
 *		postfix-expression . identifier
 *		postfix-expression -> identifier
 *		postfix-expression ++
 *		postfix-expression --
 */
static AstExpression ParsePostfixExpression(void)
{
	AstExpression expr, p;

	expr = ParsePrimaryExpression();

	while (1)
	{
		switch (CurrentToken)
		{
		case TK_LBRACKET:

			CREATE_AST_NODE(p, Expression);

			p->op = OP_INDEX;
			p->kids[0] = expr;
			NEXT_TOKEN;
			p->kids[1] = ParseExpression();
			Expect(TK_RBRACKET);

			expr = p;
			break;

		case TK_LPAREN:

			CREATE_AST_NODE(p, Expression);

			p->op = OP_CALL;
			p->kids[0] = expr;
			NEXT_TOKEN;
			if (CurrentToken != TK_RPAREN)
			{
				AstNode *tail;

				/// function call expression's second kid is actually
				/// a list of expression instead of a single expression
				p->kids[1] = ParseAssignmentExpression();
				tail = &p->kids[1]->next;
				while (CurrentToken == TK_COMMA)
				{
					NEXT_TOKEN;
					*tail = (AstNode)ParseAssignmentExpression();
					tail = &(*tail)->next;
				}
			}
			Expect(TK_RPAREN);

			expr = p;
			break;

		case TK_DOT:
		case TK_POINTER:

			CREATE_AST_NODE(p, Expression);

			p->op = (CurrentToken == TK_DOT ? OP_MEMBER : OP_PTR_MEMBER);
			p->kids[0] = expr;
			NEXT_TOKEN;
			if (CurrentToken != TK_ID)
			{
				Error(&p->coord, "Expect identifier as struct or union member");
			}
			else
			{
				p->val = TokenValue;
				NEXT_TOKEN;
			}

			expr = p;
			break;

		case TK_INC:
		case TK_DEC:

			CREATE_AST_NODE(p, Expression);

			p->op = (CurrentToken == TK_INC) ? OP_POSTINC : OP_POSTDEC;
			p->kids[0] = expr;
			NEXT_TOKEN;

			expr = p;
			break;

		default:

			return expr;
		}
	}
}
Example #8
0
static bool ParsePropertyParams(FScanner &sc, FPropertyInfo *prop, AActor *defaults, Baggage &bag)
{
	static TArray<FPropParam> params;
	static TArray<FString> strings;

	params.Clear();
	strings.Clear();
	params.Reserve(1);
	params[0].i = 0;
	if (prop->params[0] != '0')
	{
		const char * p = prop->params;
		bool nocomma;
		bool optcomma;
		while (*p)
		{
			FPropParam conv;
			FPropParam pref;

			nocomma = false;
			conv.s = NULL;
			pref.s = NULL;
			pref.i = -1;
			bag.ScriptPosition = sc;
			switch ((*p) & 223)
			{
			case 'X':	// Expression in parentheses or number.
				{
					FxExpression *x = NULL;

					if (sc.CheckString ("("))
					{
						x = new FxDamageValue(new FxIntCast(ParseExpression(sc, bag.Info)), true);
						sc.MustGetStringName(")");
					}
					else
					{
						sc.MustGetNumber();
						if (sc.Number != 0)
						{
							x = new FxDamageValue(new FxConstant(sc.Number, bag.ScriptPosition), false);
						}
					}
					conv.exp = x;
					params.Push(conv);
				}
				break;

			case 'I':
				sc.MustGetNumber();
				conv.i = sc.Number;
				break;

			case 'F':
				sc.MustGetFloat();
				conv.d = sc.Float;
				break;

			case 'Z':	// an optional string. Does not allow any numerical value.
				if (sc.CheckFloat())
				{
					nocomma = true;
					sc.UnGet();
					break;
				}
				// fall through

			case 'S':
				sc.MustGetString();
				conv.s = strings[strings.Reserve(1)] = sc.String;
				break;

			case 'T':
				sc.MustGetString();
				conv.s = strings[strings.Reserve(1)] = strbin1(sc.String);
				break;

			case 'C':
				if (sc.CheckNumber ())
				{
					int R, G, B;
					R = clamp (sc.Number, 0, 255);
					sc.CheckString (",");
					sc.MustGetNumber ();
					G = clamp (sc.Number, 0, 255);
					sc.CheckString (",");
					sc.MustGetNumber ();
					B = clamp (sc.Number, 0, 255);
					conv.i = MAKERGB(R, G, B);
					pref.i = 0;
				}
				else
				{
					sc.MustGetString ();
					conv.s = strings[strings.Reserve(1)] = sc.String;
					pref.i = 1;
				}
				break;

			case 'M':	// special case. An expression-aware parser will not need this.
				conv.i = ParseMorphStyle(sc);
				break;
				
			case 'N':	// special case. An expression-aware parser will not need this.
				conv.i = ParseThingActivation(sc);
				break;

			case 'L':	// Either a number or a list of strings
				if (sc.CheckNumber())
				{
					pref.i = 0;
					conv.i = sc.Number;
				}
				else
				{
					pref.i = 1;
					params.Push(pref);
					params[0].i++;

					do
					{
						sc.MustGetString ();
						conv.s = strings[strings.Reserve(1)] = sc.String;
						params.Push(conv);
						params[0].i++;
					}
					while (sc.CheckString(","));
					goto endofparm;
				}
				break;

			default:
				assert(false);
				break;

			}
			if (pref.i != -1)
			{
				params.Push(pref);
				params[0].i++;
			}
			params.Push(conv);
			params[0].i++;
		endofparm:
			p++;
			// Hack for some properties that have to allow comma less
			// parameter lists for compatibility.
			if ((optcomma = (*p == '_'))) 
				p++;

			if (nocomma) 
			{
				continue;
			}
			else if (*p == 0) 
			{
				break;
			}
			else if (*p >= 'a')
			{
				if (!sc.CheckString(","))
				{
					if (optcomma)
					{
						if (!sc.CheckFloat()) break;
						else sc.UnGet();
					}
					else break;
				}
			}
			else 
			{
				if (!optcomma) sc.MustGetStringName(",");
				else sc.CheckString(",");
			}
		}
	}
	// call the handler
	try
	{
		prop->Handler(defaults, bag.Info, bag, &params[0]);
	}
	catch (CRecoverableError &error)
	{
		sc.ScriptError("%s", error.GetMessage());
	}

	return true;
}
Example #9
0
FxExpression *ParseParameter(FScanner &sc, PClassActor *cls, PType *type, bool constant)
{
	FxExpression *x = NULL;
	int v;

	if (type == TypeSound)
	{
		sc.MustGetString();
		x = new FxConstant(FSoundID(sc.String), sc);
	}
	else if (type == TypeBool || type == TypeSInt32 || type == TypeFloat64)
	{
		x = ParseExpression (sc, cls, constant);
		if (constant && !x->isConstant())
		{
			sc.ScriptMessage("Default parameter must be constant.");
			FScriptPosition::ErrorCounter++;
		}
		// Do automatic coercion between bools, ints and floats.
		if (type == TypeBool)
		{
			x = new FxBoolCast(x);
		}
		else if (type == TypeSInt32)
		{
			x = new FxIntCast(x);
		}
		else
		{
			x = new FxFloatCast(x);
		}
	}
	else if (type == TypeName || type == TypeString)
	{
		sc.SetEscape(true);
		sc.MustGetString();
		sc.SetEscape(false);
		if (type == TypeName)
		{
			x = new FxConstant(sc.String[0] ? FName(sc.String) : NAME_None, sc);
		}
		else
		{
			x = new FxConstant(strbin1(sc.String), sc);
		}
	}
	else if (type == TypeColor)
	{
		sc.MustGetString ();
		if (sc.Compare("none"))
		{
			v = -1;
		}
		else if (sc.Compare(""))
		{
			v = 0;
		}
		else
		{
			int c = V_GetColor (NULL, sc.String);
			// 0 needs to be the default so we have to mark the color.
			v = MAKEARGB(1, RPART(c), GPART(c), BPART(c));
		}
		ExpVal val;
		val.Type = TypeColor;
		val.Int = v;
		x = new FxConstant(val, sc);
	}
	else if (type == TypeState)
	{
		// This forces quotation marks around the state name.
		sc.MustGetToken(TK_StringConst);
		if (sc.String[0] == 0 || sc.Compare("None"))
		{
			x = new FxConstant((FState*)NULL, sc);
		}
		else if (sc.Compare("*"))
		{
			if (constant) 
			{
				x = new FxConstant((FState*)(intptr_t)-1, sc);
			}
			else sc.ScriptError("Invalid state name '*'");
		}
		else
		{
			x = new FxMultiNameState(sc.String, sc);
		}
	}
	else if (type->GetClass() == RUNTIME_CLASS(PClassPointer))
	{	// Actor name
		sc.SetEscape(true);
		sc.MustGetString();
		sc.SetEscape(false);
		x = new FxClassTypeCast(static_cast<PClassPointer *>(type)->ClassRestriction, new FxConstant(FName(sc.String), sc));
	}
	else
	{
		assert(false && "Unknown parameter type");
		x = NULL;
	}
	return x;
}
Example #10
0
static void ParseUserVariable (FScanner &sc, PSymbolTable *symt, PClassActor *cls)
{
	PType *type;
	int maxelems = 1;

	// Only non-native classes may have user variables.
	if (!cls->bRuntimeClass)
	{
		sc.ScriptError("Native classes may not have user variables");
	}

	// Read the type and make sure it's acceptable.
	sc.MustGetAnyToken();
	if (sc.TokenType != TK_Int && sc.TokenType != TK_Float)
	{
		sc.ScriptMessage("User variables must be of type 'int' or 'float'");
		FScriptPosition::ErrorCounter++;
	}
	type = sc.TokenType == TK_Int ? (PType *)TypeSInt32 : (PType *)TypeFloat64;

	sc.MustGetToken(TK_Identifier);
	// For now, restrict user variables to those that begin with "user_" to guarantee
	// no clashes with internal member variable names.
	if (sc.StringLen < 6 || strnicmp("user_", sc.String, 5) != 0)
	{
		sc.ScriptMessage("User variable names must begin with \"user_\"");
		FScriptPosition::ErrorCounter++;
	}

	FName symname = sc.String;

	// We must ensure that we do not define duplicates, even when they come from a parent table.
	if (symt->FindSymbol(symname, true) != NULL)
	{
		sc.ScriptMessage ("'%s' is already defined in '%s' or one of its ancestors.",
			symname.GetChars(), cls ? cls->TypeName.GetChars() : "Global");
		FScriptPosition::ErrorCounter++;
		return;
	}

	if (sc.CheckToken('['))
	{
		FxExpression *expr = ParseExpression(sc, cls, true);
		if (!expr->isConstant())
		{
			sc.ScriptMessage("Array size must be a constant");
			FScriptPosition::ErrorCounter++;
			maxelems = 1;
		}
		else
		{
			maxelems = static_cast<FxConstant *>(expr)->GetValue().GetInt();
		}
		sc.MustGetToken(']');
		if (maxelems <= 0)
		{
			sc.ScriptMessage("Array size must be positive");
			FScriptPosition::ErrorCounter++;
			maxelems = 1;
		}
		type = NewArray(type, maxelems);
	}
	sc.MustGetToken(';');

	PField *sym = cls->AddField(symname, type, 0);
	if (sym == NULL)
	{
		sc.ScriptMessage ("'%s' is already defined in '%s'.",
			symname.GetChars(), cls ? cls->TypeName.GetChars() : "Global");
		FScriptPosition::ErrorCounter++;
	}
}
Example #11
0
/// ParseDeclarationTypeSpec - Parse a declaration type spec construct.
/// 
///   [R502]:
///     declaration-type-spec :=
///         intrinsic-type-spec
///      or TYPE ( derived-type-spec )
///      or CLASS ( derived-type-spec )
///      or CLASS ( * )
bool Parser::ParseDeclarationTypeSpec(DeclSpec &DS, bool AllowSelectors,
                                      bool AllowOptionalCommaAfterCharLength) {
  // [R403]:
  //   intrinsic-type-spec :=
  //       INTEGER [ kind-selector ]
  //    or REAL [ kind-selector ]
  //    or DOUBLE PRECISION
  //    or COMPLEX [ kind-selector ]
  //    or DOUBLE COMPLEX
  //    or CHARACTER [ char-selector ]
  //    or BYTE
  //    or LOGICAL [ kind-selector ]
  switch (Tok.getKind()) {
  default:
    DS.SetTypeSpecType(DeclSpec::TST_unspecified);
    break;
  case tok::kw_INTEGER:
    DS.SetTypeSpecType(DeclSpec::TST_integer);
    break;
  case tok::kw_REAL:
    DS.SetTypeSpecType(DeclSpec::TST_real);
    break;
  case tok::kw_COMPLEX:
    DS.SetTypeSpecType(DeclSpec::TST_complex);
    break;
  case tok::kw_CHARACTER:
    DS.SetTypeSpecType(DeclSpec::TST_character);
    break;
  case tok::kw_BYTE:
    DS.SetTypeSpecType(DeclSpec::TST_logical);
    DS.setByte(); // equivalent to Kind = 1
    break;
  case tok::kw_LOGICAL:
    DS.SetTypeSpecType(DeclSpec::TST_logical);
    break;
  case tok::kw_DOUBLEPRECISION:
    DS.SetTypeSpecType(DeclSpec::TST_real);
    DS.setDoublePrecision(); // equivalent to Kind = 8
    break;
  case tok::kw_DOUBLECOMPLEX:
    DS.SetTypeSpecType(DeclSpec::TST_complex);
    DS.setDoublePrecision(); // equivalent to Kind = 8
    break;
  }

  if (DS.getTypeSpecType() == DeclSpec::TST_unspecified)
    if (ParseTypeOrClassDeclTypeSpec(DS))
      return true;

  ExprResult Kind;
  ExprResult Len;

  // FIXME: no Kind for double complex, double precision and byte
  switch (DS.getTypeSpecType()) {
  case DeclSpec::TST_struct:
    break;
  default:
    ConsumeToken();
    if (ConsumeIfPresent(tok::star)) {
      // FIXME: proper obsolete COMPLEX*16 support
      ConsumeAnyToken();
      DS.setDoublePrecision();
    }

    if (!AllowSelectors)
      break;
    if (ConsumeIfPresent(tok::l_paren)) {
      Kind = ParseSelector(true);
      if (Kind.isInvalid())
        return true;

      if(!ExpectAndConsume(tok::r_paren, 0, "", tok::r_paren))
        return true;
    }

    break;
  case DeclSpec::TST_character:
    // [R424]:
    //   char-selector :=
    //       length-selector
    //    or ( LEN = type-param-value , KIND = scalar-int-initialization-expr )
    //    or ( type-param-value , #
    //    #    [ KIND = ] scalar-int-initialization-expr )
    //    or ( KIND = scalar-int-initialization-expr [, LEN = type-param-value])
    //
    // [R425]:
    //   length-selector :=
    //       ( [ LEN = ] type-param-value )
    //    or * char-length [,]
    //
    // [R426]:
    //   char-length :=
    //       ( type-param-value )
    //    or scalar-int-literal-constant
    //
    // [R402]:
    //   type-param-value :=
    //       scalar-int-expr
    //    or *
    //    or :
    ConsumeToken();

    if(ConsumeIfPresent(tok::star)) {
      ParseCharacterStarLengthSpec(DS);
      if(AllowOptionalCommaAfterCharLength)
        ConsumeIfPresent(tok::comma);
    } else {
      if (!AllowSelectors)
        break;
      if(ConsumeIfPresent(tok::l_paren)) {
        if(IsPresent(tok::kw_LEN)) {
          Len = ParseSelector(false);
          if (Len.isInvalid())
            return true;
        } else if(IsPresent(tok::kw_KIND)) {
          Kind = ParseSelector(true);
          if (Kind.isInvalid())
            return true;
        } else {
          Len = ParseExpectedFollowupExpression("(");
          if(Len.isInvalid())
            return true;
        }

        if(ConsumeIfPresent(tok::comma)) {
          // FIXME:
          if (Tok.is(tok::kw_LEN)) {
            if (Len.isInvalid())
              return Diag.ReportError(Tok.getLocation(),
                                      "multiple LEN selectors for this type");
            Len = ParseSelector(false);
            if (Len.isInvalid())
              return true;
          } else if (Tok.is(tok::kw_KIND)) {
            if (Kind.isInvalid())
              return Diag.ReportError(Tok.getLocation(),
                                      "multiple KIND selectors for this type");
            Kind = ParseSelector(true);
            if (Kind.isInvalid())
              return true;
          } else {
            if (Kind.isInvalid())
              return Diag.ReportError(Tok.getLocation(),
                                      "multiple KIND selectors for this type");

            ExprResult KindExpr = ParseExpression();
            Kind = KindExpr;
          }
        }

        if(!ExpectAndConsume(tok::r_paren))
          return true;
      }
    }

    break;
  }

  // Set the selectors for declspec.
  if(Kind.isUsable()) DS.setKindSelector(Kind.get());
  if(Len.isUsable())  DS.setLengthSelector(Len.get());
  return false;
}
Example #12
0
PRIVATE void ParseStatement( void )
{
    Accept( IDENTIFIER );
    Accept( ASSIGNMENT );       /* ":=" has token name ASSIGNMENT.          */ 
    ParseExpression();
}
Example #13
0
struct Expression* ParseAtom(const RegexpTokenType* token_stream, int* pos) {
    int origpos = *pos;
    char c = token_stream[*pos];
    if(IS_LITERAL_TOKEN(c)) {
	/* Atom := string of literal characters/ANY_CHAR/LINE_START/LINE_END */
	struct LiteralStringExpression* result =
	    malloc(sizeof(struct LiteralStringExpression));
	int num_tokens;
	result->base.typecode = LITERAL_STRING_EXPRESSION_TYPE;
	result->base.group_number = NO_GROUP;

	for( ; token_stream[*pos] != 0; (*pos)++) {
	    if (!IS_LITERAL_TOKEN(token_stream[*pos])) {
		break;
	    }
	}
	num_tokens = (*pos) - origpos;
	result->literal_string = malloc((num_tokens + 1) * sizeof(RegexpTokenType));
	result->literal_string[num_tokens] = 0; /* null terminate */
	memmove(result->literal_string, &token_stream[origpos], num_tokens*sizeof(RegexpTokenType));
	return (struct Expression*)result;
    }

    switch (c) {
    case SPECIAL_SET_PREFIX: {
	/* Atom := SPECIAL_SET_PREFIX <letter>, just invoke its regexp */
	(*pos)++;
	if (predefined_char_classes[token_stream[*pos]].token_string != NULL) {
	    int pre_pos = 0;
	    struct Expression* result =
		ParseExpression(predefined_char_classes[token_stream[*pos]].token_string, &pre_pos);
	    (*pos)++;
	    return result;
	}
	switch(token_stream[*pos]) {
	case 'B':   /* Between \w and \w OR between \W and \W */
	case 'b': { /* Between \w and \W OR between \W and \w */
	    int temp_pos = 0;
	    struct ZeroWidthExpression* left =
		malloc(sizeof(struct ZeroWidthExpression));
	    struct ZeroWidthExpression* right =
		malloc(sizeof(struct ZeroWidthExpression));
	    struct UnionExpression* result =
		malloc(sizeof(struct UnionExpression));

	    left->base.typecode = ZERO_WIDTH_EXPRESSION_TYPE;
	    left->base.group_number = NO_GROUP;
	    temp_pos=0; ParseSet(predefined_char_classes['w'].token_string,
				 &temp_pos, left->preceding_set);
	    if (token_stream[*pos] == 'b') {
		temp_pos=0; ParseSet(predefined_char_classes['W'].token_string,
				     &temp_pos, left->following_set);
	    } else {
		temp_pos=0; ParseSet(predefined_char_classes['w'].token_string,
				     &temp_pos, left->following_set);
	    }

	    right->base.typecode = ZERO_WIDTH_EXPRESSION_TYPE;
	    right->base.group_number = NO_GROUP;
	    temp_pos=0; ParseSet(predefined_char_classes['W'].token_string,
				 &temp_pos, right->preceding_set);
	    if (token_stream[*pos] == 'b') {
		temp_pos=0; ParseSet(predefined_char_classes['w'].token_string,
				     &temp_pos, right->following_set);
	    } else {
		temp_pos=0; ParseSet(predefined_char_classes['W'].token_string,
				     &temp_pos, right->following_set);
	    }

	    result->base.typecode = UNION_EXPRESSION_TYPE;
	    result->base.group_number = NO_GROUP;
	    result->left_expression = (struct Expression*)left;
	    result->right_expression = (struct Expression*)right;
	    (*pos)++;
	    return (struct Expression*)result;
	}
	}
	goto parse_error;
    }
    case ANY_CHAR: {
	struct CharSetExpression* result =
	    malloc(sizeof(struct CharSetExpression));
	result->base.typecode = CHARSET_EXPRESSION_TYPE;
	result->base.group_number = NO_GROUP;
	SetAllCharSet(result->set);
	(*pos)++;
	return (struct Expression*)result;
    }
    case LINE_START: {
	struct ZeroWidthExpression* result =
	    malloc(sizeof(struct ZeroWidthExpression));
	result->base.typecode = ZERO_WIDTH_EXPRESSION_TYPE;
	result->base.group_number = NO_GROUP;
	ZeroOutCharSet(result->preceding_set);
	BitArrayInsert(result->preceding_set, BEFORE_STRING_CHAR);
	SetAllCharSet(result->following_set);
	(*pos)++;
	return (struct Expression*)result;
    }
    case LINE_END: {
	struct ZeroWidthExpression* result =
	    malloc(sizeof(struct ZeroWidthExpression));
	result->base.typecode = ZERO_WIDTH_EXPRESSION_TYPE;
	result->base.group_number = NO_GROUP;
	SetAllCharSet(result->preceding_set);
	ZeroOutCharSet(result->following_set);
	BitArrayInsert(result->following_set, AFTER_STRING_CHAR);
	(*pos)++;
	return (struct Expression*)result;
    }
    case SET_OPEN: {
	/* Atom := character set */
	struct CharSetExpression* result =
	    malloc(sizeof(struct CharSetExpression));
	result->base.typecode = CHARSET_EXPRESSION_TYPE;
	result->base.group_number = NO_GROUP;
	if (ParseSet(token_stream, pos, result->set) == 0) {
	    destroy_expression((struct Expression*)result);
	    goto parse_error;
	}
	return (struct Expression*)result;
    }
    case GROUP_OPEN: {
        /* Atom := GROUP_OPEN Expression GROUP_CLOSE */
	int open_pos = *pos;
	int group_num = 0;
	struct Expression* expr =
	    ((*pos)++, ParseExpression(token_stream, pos));
	int i;
	if (expr == NULL || token_stream[*pos] != GROUP_CLOSE) {
	    destroy_expression(expr);
	    goto parse_error;
	}
	/* Find group number by counting preceding (s */
	for(i=0; i<open_pos; i++) {
	    if (token_stream[i] == GROUP_OPEN) {
		group_num++;
	    }
	}
	expr->group_number = group_num;
	(*pos)++;
	return expr;
    }
    default:
	/* Unexpected char, parse error */
	goto parse_error;
    }
parse_error:
    *pos = origpos;
    return NULL;
}
Example #14
0
File: expr.c Project: M-ike/work
/**
 *  primary-expression:
 *		ID
 *		constant
 *		string-literal
 *		( expression )
 */
static AstExpression ParsePrimaryExpression(void)
{
	AstExpression expr;


	switch (CurrentToken)
	{
	case TK_ID:

		CREATE_AST_NODE(expr, Expression);

		expr->op = OP_ID;
		expr->val = TokenValue;
		NEXT_TOKEN;

		return expr;

	/// Notice: Only when parsing constant and string literal,
	/// ty member in astExpression is used since from OP_CONST
	/// and OP_STR alone the expression's type can't be determined
	case TK_INTCONST:
	case TK_UINTCONST:
	case TK_LONGCONST:
	case TK_ULONGCONST:
	case TK_LLONGCONST:
	case TK_ULLONGCONST:
	case TK_FLOATCONST:
	case TK_DOUBLECONST:
	case TK_LDOUBLECONST:

		CREATE_AST_NODE(expr, Expression);

		if (CurrentToken >= TK_FLOATCONST)
			CurrentToken++;

		/// nasty, requires that both from TK_INTCONST to TK_LDOUBLECONST
		/// and from INT to LDOUBLE are consecutive
		expr->ty = T(INT + CurrentToken - TK_INTCONST);
		expr->op = OP_CONST;
		expr->val = TokenValue;
		NEXT_TOKEN;

		return expr;

	case TK_STRING:
	case TK_WIDESTRING:

		CREATE_AST_NODE(expr, Expression);

		expr->ty = ArrayOf(((String)TokenValue.p)->len + 1, CurrentToken == TK_STRING ? T(CHAR) : WCharType);
		expr->op = OP_STR;
		expr->val = TokenValue;
		NEXT_TOKEN;

		return expr;

	case TK_LPAREN:

		NEXT_TOKEN;
		expr = ParseExpression();
		Expect(TK_RPAREN);

		return expr;

	default:
		Error(&TokenCoord, "Expect identifier, string, constant or (");
		return Constant0;
	}
}
Example #15
0
static FProduction *ParseExpression (FCommandLine &argv, int &parsept)
{
	if (parsept >= argv.argc())
		return NULL;

	const char *token = argv[parsept++];
	FProduction *prod1 = NULL, *prod2 = NULL, *prod3 = NULL;

	if (IsFloat (token))
	{
		return NewDoubleProd (atof(token));
	}
	else if (stricmp (token, "true") == 0)
	{
		return NewDoubleProd (1.0);
	}
	else if (stricmp (token, "false") == 0)
	{
		return NewDoubleProd (0.0);
	}
	else
	{
		for (size_t i = 0; i < countof(Producers); ++i)
		{
			if (strcmp (Producers[i].Token, token) == 0)
			{
				prod1 = ParseExpression (argv, parsept);
				prod2 = ParseExpression (argv, parsept);
				if (prod1 == NULL || prod2 == NULL)
				{
					goto missing;
				}
				if (Producers[i].StringProducer == NULL)
				{
					DoubleCoerce (prod1, prod2);
				}
				else if (Producers[i].DoubleProducer == NULL)
				{
					MustStringCoerce (prod1, prod2);
				}
				else
				{
					MaybeStringCoerce (prod1, prod2);
				}
				if (prod1->Type == PROD_String)
				{
					prod3 = Producers[i].StringProducer ((FStringProd *)prod1, (FStringProd *)prod2);
				}
				else
				{
					prod3 = Producers[i].DoubleProducer ((FDoubleProd *)prod1, (FDoubleProd *)prod2);
				}
				goto done;
			}
		}
		if (strcmp ("!", token) == 0)
		{
			prod1 = ParseExpression (argv, parsept);
			if (prod1 == NULL)
			{
				goto missing;
			}
			if (prod1->Type == PROD_String)
			{
				prod1 = StringToDouble (prod1);
			}
			prod3 = NewDoubleProd (!static_cast<FDoubleProd *>(prod1)->Value);
			goto done;
		}
		return NewStringProd (token);
	}

missing:
	Printf ("Missing argument to %s\n", token);

done:
	if (prod2 != NULL) M_Free (prod2);
	if (prod1 != NULL) M_Free (prod1);
	return prod3;
}
Example #16
0
FxExpression *ParseParameter(FScanner &sc, PClass *cls, char type, bool constant)
{
	FxExpression *x = NULL;
	int v;

	switch(type)
	{
	case 'S':
	case 's':		// Sound name
		sc.MustGetString();
		x = new FxConstant(FSoundID(sc.String), sc);
		break;

	case 'M':
	case 'm':		// Actor name
		sc.SetEscape(true);
		sc.MustGetString();
		sc.SetEscape(false);
		x = new FxClassTypeCast(RUNTIME_CLASS(AActor), new FxConstant(FName(sc.String), sc));
		break;

	case 'T':
	case 't':		// String
		sc.SetEscape(true);
		sc.MustGetString();
		sc.SetEscape(false);
		x = new FxConstant(sc.String[0]? FName(sc.String) : NAME_None, sc);
		break;

	case 'C':
	case 'c':		// Color
		sc.MustGetString ();
		if (sc.Compare("none"))
		{
			v = -1;
		}
		else if (sc.Compare(""))
		{
			v = 0;
		}
		else
		{
			int c = V_GetColor (NULL, sc.String);
			// 0 needs to be the default so we have to mark the color.
			v = MAKEARGB(1, RPART(c), GPART(c), BPART(c));
		}
		{
			ExpVal val;
			val.Type = VAL_Color;
			val.Int = v;
			x = new FxConstant(val, sc);
			break;
		}

	case 'L':
	case 'l':
	{
		// This forces quotation marks around the state name.
		sc.MustGetToken(TK_StringConst);
		if (sc.String[0] == 0 || sc.Compare("None"))
		{
			x = new FxConstant((FState*)NULL, sc);
		}
		else if (sc.Compare("*"))
		{
			if (constant) 
			{
				x = new FxConstant((FState*)(intptr_t)-1, sc);
			}
			else sc.ScriptError("Invalid state name '*'");
		}
		else
		{
			x = new FxMultiNameState(sc.String, sc);
		}
		break;
	}

	case 'X':
	case 'x':
	case 'Y':
	case 'y':
		x = ParseExpression (sc, cls);
		if (constant && !x->isConstant())
		{
			sc.ScriptMessage("Default parameter must be constant.");
			FScriptPosition::ErrorCounter++;
		}
		break;

	default:
		assert(false);
		return NULL;
	}
	return x;
}
Example #17
0
static void ParseUserVariable (FScanner &sc, PSymbolTable *symt, PClass *cls)
{
	FExpressionType valuetype;

	// Only non-native classes may have user variables.
	if (!cls->bRuntimeClass)
	{
		sc.ScriptError("Native classes may not have user variables");
	}

	// Read the type and make sure it's int.
	sc.MustGetAnyToken();
	if (sc.TokenType != TK_Int)
	{
		sc.ScriptMessage("User variables must be of type int");
		FScriptPosition::ErrorCounter++;
	}
	valuetype = VAL_Int;

	sc.MustGetToken(TK_Identifier);
	// For now, restrict user variables to those that begin with "user_" to guarantee
	// no clashes with internal member variable names.
	if (sc.StringLen < 6 || strnicmp("user_", sc.String, 5) != 0)
	{
		sc.ScriptMessage("User variable names must begin with \"user_\"");
		FScriptPosition::ErrorCounter++;
	}



	FName symname = sc.String;
	if (sc.CheckToken('['))
	{
		FxExpression *expr = ParseExpression(sc, cls);
		int maxelems = expr->EvalExpression(NULL).GetInt();
		delete expr;
		sc.MustGetToken(']');
		if (maxelems <= 0)
		{
			sc.ScriptMessage("Array size must be positive");
			FScriptPosition::ErrorCounter++;
			maxelems = 1;
		}
		valuetype.MakeArray(maxelems);
	}
	sc.MustGetToken(';');

	// We must ensure that we do not define duplicates, even when they come from a parent table.
	if (symt->FindSymbol(symname, true) != NULL)
	{
		sc.ScriptMessage ("'%s' is already defined in '%s' or one of its ancestors.",
			symname.GetChars(), cls ? cls->TypeName.GetChars() : "Global");
		FScriptPosition::ErrorCounter++;
		return;
	}

	PSymbolVariable *sym = new PSymbolVariable(symname);
	sym->offset = cls->Extend(sizeof(int) * (valuetype.Type == VAL_Array ? valuetype.size : 1));
	sym->ValueType = valuetype;
	sym->bUserVar = true;
	if (symt->AddSymbol(sym) == NULL)
	{
		delete sym;
		sc.ScriptMessage ("'%s' is already defined in '%s'.",
			symname.GetChars(), cls ? cls->TypeName.GetChars() : "Global");
		FScriptPosition::ErrorCounter++;
	}
}
Example #18
0
static void ParseNativeVariable (FScanner &sc, PSymbolTable * symt, PClass *cls)
{
	FExpressionType valuetype;

	if (sc.LumpNum == -1 || Wads.GetLumpFile(sc.LumpNum) > 0)
	{
		sc.ScriptMessage ("variables can only be imported by internal class and actor definitions!");
		FScriptPosition::ErrorCounter++;
	}

	// Read the type and make sure it's int or float.
	sc.MustGetAnyToken();
	switch (sc.TokenType)
	{
	case TK_Int:
		valuetype = VAL_Int;
		break;

	case TK_Float:
		valuetype = VAL_Float;
		break;

	case TK_Angle_t:
		valuetype = VAL_Angle;
		break;

	case TK_Fixed_t:
		valuetype = VAL_Fixed;
		break;

	case TK_Bool:
		valuetype = VAL_Bool;
		break;

	case TK_Identifier:
		valuetype = VAL_Object;
		// Todo: Object type
		sc.ScriptError("Object type variables not implemented yet!");
		break;

	default:
		sc.ScriptError("Invalid variable type %s", sc.String);
		return;
	}

	sc.MustGetToken(TK_Identifier);
	FName symname = sc.String;
	if (sc.CheckToken('['))
	{
		FxExpression *expr = ParseExpression (sc, cls);
		int maxelems = expr->EvalExpression(NULL).GetInt();
		delete expr;
		sc.MustGetToken(']');
		valuetype.MakeArray(maxelems);
	}
	sc.MustGetToken(';');

	const FVariableInfo *vi = FindVariable(symname, cls);
	if (vi == NULL)
	{
		sc.ScriptError("Unknown native variable '%s'", symname.GetChars());
	}

	PSymbolVariable *sym = new PSymbolVariable(symname);
	sym->offset = vi->address;	// todo
	sym->ValueType = valuetype;
	sym->bUserVar = false;

	if (symt->AddSymbol (sym) == NULL)
	{
		delete sym;
		sc.ScriptMessage ("'%s' is already defined in '%s'.",
			symname.GetChars(), cls? cls->TypeName.GetChars() : "Global");
		FScriptPosition::ErrorCounter++;
	}
}
  double CalculateExpression(const std::string& i_string,
                             size_t& o_errorPos)
  {
    std::vector<ExpressionItem*> items;
    size_t maxNestingLevel = 0;
    size_t parseResult = ParseExpression(i_string, items, maxNestingLevel);
    if (parseResult != kDefaultErrorPos)
    {
      o_errorPos = parseResult;
      return 0.0;
    }

    size_t validateResult = ValidateExpression(items);
    if (validateResult != kDefaultErrorPos)
    {
      o_errorPos = validateResult;
      return 0.0;
    }

    size_t nestingLevel = maxNestingLevel + 1;
    while (true)
    {
      nestingLevel--;

      size_t loc = 0;
      while (loc < items.size())
      {
        while (loc < items.size() &&
               (items[loc]->NestingLevel() != nestingLevel))
        {
          loc++;
        }

        if (loc >= items.size())
        {
          break;
        }

        size_t startLoc = loc;
        while (loc < items.size() &&
               (items[loc]->NestingLevel() == nestingLevel))
        {
          loc++;
        }
        size_t endLoc = loc;

        if (startLoc != endLoc)
        {
          double value = CalculateSequence(items, startLoc, endLoc);

          for (size_t i = startLoc; i < endLoc; ++i)
          {
            delete items[i];
          }
          items.erase(items.begin() + startLoc, items.begin() + (endLoc - 1));

          Operand* operand = new Operand(value, nestingLevel - 1, 0);
          items[startLoc] = operand;
        }
      }

      if (nestingLevel == 0)
      {
        break;
      }
    }

    assert(items.size() == 1);
    Operand* operand = dynamic_cast<Operand*>(items[0]);
    double result = operand->GetValue();
    delete operand;

    return result;
  }
Example #20
0
// Atom ::= "(" Expression ")" | "[" [^] Range "]" | Characters
Instruction* ParseAtom(const char **ppc, ParseInfo &info)
{
  Instruction *i = 0;
  const char *pc = *ppc;
  
  switch (*pc)
  {
    case '(':
    {
      Group::TriState dnl = Group::Inherit;
      Group::TriState nc = Group::Inherit;
      Group::TriState ml = Group::Inherit;
      bool capture = true;
      bool consume = true;
      bool invert = false;
      bool reverse = false;
      std::string name = "";
      
      ++pc;
      
      if (*pc == '?')
      {
        ++pc;
        if (*pc == '#')
        {
          // skip everything until ) and from behave as if ParseAtom was
          // called starting next character
          ++pc;
          while (*pc != ')')
          {
            if (*pc == '\0')
            {
              return 0;
            }
            ++pc;
          }
          *ppc = ++pc;
          return ParseAtom(ppc, info);
        }
        if (*pc == ':')
        {
          capture = false;
          ++pc;
        }
        else if (*pc == '(')
        {
          // conditional
          ++pc;
          
          std::string cond;
          while (*pc != ')')
          {
            if (*pc == '\0')
            {
              return 0;
            }
            cond.push_back(*pc);
            ++pc;
          }
          ++pc;
          
          Instruction *ci = ParseExpression(&pc, info);
          if (!ci || *pc != ')')
          {
            if (ci)
            {
              delete ci;
            }
            return 0;
          }
          ++pc;
          
          Alternative *alt = dynamic_cast<Alternative*>(ci);
          Instruction *ifTrue, *ifFalse;
          if (alt == 0)
          {
            ifTrue = ci;
            ifFalse = 0;
          }
          else
          {
            ifTrue = alt->first()->clone();
            ifFalse = alt->second()->clone();
            delete alt;
          }
          
          *ppc = pc;
          int index = 0;
          if (sscanf(cond.c_str(), "%d", &index) != 1)
          {
            return new Conditional(cond, ifTrue, ifFalse);
          }
          else
          {
            return new Conditional(index, ifTrue, ifFalse);
          }
        }
        else if (*pc == 'P')
        {
          ++pc;
          if (*pc == '<')
          {
            ++pc;
            while (*pc != '>')
            {
              if (*pc == '\0')
              {
                return 0;
              }
              name.push_back(*pc);
              ++pc;
            }
            ++pc;
          }
          else if (*pc == '=')
          {
            std::string name;
            ++pc;
            while (*pc != ')')
            {
              if (*pc == '\0')
              {
                return 0;
              }
              name.push_back(*pc);
              ++pc;
            }
            ++pc;
            *ppc = pc;
            return new Backsubst(name);
          }
          else
          {
            return 0;
          }
        }
        else if (*pc == '=')
        {
          // positive lookahead
          capture = false;
          consume = false;
          ++pc;
        }
        else if (*pc == '!')
        {
          // negative lookahead
          capture = false;
          consume = false;
          invert = true;
          ++pc;
        }
        else if (*pc == '<')
        {
          ++pc;
          if (*pc == '=')
          {
            // positive lookbehind
            capture = false;
            consume = false;
            reverse = true;
            ++pc;
          }
          else if (*pc == '!')
          {
            // negative lookbehind
            capture = false;
            consume = false;
            reverse = true;
            invert = true;
            ++pc;
          }
          else
          {
            Log::PrintError("[gcore] rex/ParseAtom: Invalid group format");
            return 0;
          }
        }
        else if (*pc == 'i' || *pc == 'm' || *pc == 's' || *pc == '-')
        {
          //capture = false;
          //consume = false;
          if (*pc == 'i')
          {
            // case sensitive off
            nc = Group::On;
            ++pc;
          }
          if (*pc == 'm')
          {
            // multiline on (. matches \r\n)
            ml = Group::On;
            ++pc;
          }
          if (*pc == 's')
          {
            // dot matches new line on
            dnl = Group::On;
            ++pc;
          }
          if (*pc == '-')
          {
            ++pc;
            if (*pc == 'i')
            {
              // case sensitive on
              nc = Group::Off;
              ++pc;
            }
            if (*pc == 'm')
            {
              // multiline off
              ml = Group::Off;
              ++pc;
            }
            if (*pc == 's')
            {
              // dot matches newline off
              dnl = Group::Off;
              ++pc;
            }
          }
          if (*pc != ':' && *pc != ')')
          {
            // either followed by : or group end (meaning we just want to change exp exec flags)
            Log::PrintError("[gcore] rex/ParseAtom: Invalid group format");
            return 0;
          }
          
          if (*pc == ':')
          {
            ++pc;
            // would having a closing parent here be problematic
          }
          else
          {
            capture = false;
            consume = false;
          }
        }
      }
      
      int gidx = (capture ? (++(info.numGroups)) : -1);
      unsigned short flags = (unsigned short)(reverse ? Rex::Reverse : 0);
      
      if (*pc != ')')
      {
        i = ParseExpression(&pc, info);
      }

      if (*pc != ')')
      {
        if (i)
        {
          delete i;
        }
        return 0;
      }
      
#ifdef _DEBUG_REX
      Log::PrintDebug("[gcore] rex/ParseAtom: Create group");
      Log::SetIndentLevel(Log::GetIndentLevel()+1);
      Log::PrintDebug("index: %d", gidx);
      Log::PrintDebug("invert: %d", invert);
      Log::PrintDebug("consume: %d", consume);
      Log::PrintDebug("flags: %d", flags);
      Log::PrintDebug("nc: %d", nc);
      Log::PrintDebug("ml: %d", ml);
      Log::PrintDebug("dnl: %d", dnl);
      Log::PrintDebug("name: %d", name.c_str());
      Log::PrintDebug("code: ");
      if (i)
      {
        std::ostringstream oss;
        
        Log::SetIndentLevel(Log::GetIndentLevel()+1)
        i->toStream(oss);
        Log::PrintDebug(oss.str().c_str());
        Log::SetIndentLevel(Log::GetIndentLevel()-1)
      }
      Log::SetIndentLevel(Log::GetIndentLevel()-1);
#endif
      
      i = new Group(gidx, i, !consume, invert, flags, nc, ml, dnl, name);
      
#ifdef _DEBUG_REX
      Log::PrintDebug("[gcore] rex/ParseAtom: Group created");
#endif
      ++pc;
      
      break;
    }
    case '[':
    {
      bool inv = false;
      ++pc;
      if (*pc == '^')
      {
        inv = true;
        ++pc;
      }
      i = ParseRange(&pc, inv, info);
      if (!i)
      {
        return 0;
      }
      if (*pc != ']')
      {
        Log::PrintError("[gcore] rex/ParseAtom: Invalid character '%c' in expression, expected ']'", *pc);
        if (i)
        {
          delete i;
        }
        return 0;
      }
      ++pc;
      break;
    }
    default:
      i = ParseCharacters(&pc, info);
      if (!i)
      {
        i = ParseZerowidth(&pc, info);
        if (!i)
        {
          return 0;
        }
      }
  }
  *ppc = pc;
  return i;
}
Example #21
0
// ParsePrimaryExpr - Parse a primary expression.
//
//   [R701]:
//     primary :=
//         constant
//      or designator
//      or array-constructor
//      or structure-constructor
//      or function-reference
//      or type-param-inquiry
//      or type-param-name
//      or ( expr )
Parser::ExprResult Parser::ParsePrimaryExpr(bool IsLvalue) {
  ExprResult E;
  SourceLocation Loc = Tok.getLocation();

  // FIXME: Add rest of the primary expressions.
  switch (Tok.getKind()) {
  default:
    if (isTokenIdentifier())
      goto possible_keyword_as_ident;
    Diag.Report(getExpectedLoc(), diag::err_expected_expression);
    return ExprError();
  case tok::error:
    Lex();
    return ExprError();
  case tok::l_paren: {
    ConsumeParen();

    E = ParseExpression();
    // complex constant.
    if(ConsumeIfPresent(tok::comma)) {
      if(E.isInvalid()) return E;
      auto ImPart = ParseExpectedFollowupExpression(",");
      if(ImPart.isInvalid()) return ImPart;
      E = Actions.ActOnComplexConstantExpr(Context, Loc,
                                           getMaxLocationOfCurrentToken(),
                                           E, ImPart);
    }

    ExpectAndConsume(tok::r_paren, 0, "", tok::r_paren);
    break;
  }
  case tok::l_parenslash : {
    return ParseArrayConstructor();
    break;
  }
  case tok::logical_literal_constant: {
    std::string NumStr;
    CleanLiteral(Tok, NumStr);

    StringRef Data(NumStr);
    std::pair<StringRef, StringRef> StrPair = Data.split('_');
    E = LogicalConstantExpr::Create(Context, getTokenRange(),
                                    StrPair.first, Context.LogicalTy);
    SetKindSelector(cast<ConstantExpr>(E.get()), StrPair.second);
    ConsumeToken();
    break;
  }
  case tok::binary_boz_constant:
  case tok::octal_boz_constant:
  case tok::hex_boz_constant: {
    std::string NumStr;
    CleanLiteral(Tok, NumStr);

    StringRef Data(NumStr);
    std::pair<StringRef, StringRef> StrPair = Data.split('_');
    E = BOZConstantExpr::Create(Context, Loc,
                                getMaxLocationOfCurrentToken(),
                                StrPair.first);
    SetKindSelector(cast<ConstantExpr>(E.get()), StrPair.second);
    ConsumeToken();
    break;
  }
  case tok::char_literal_constant: {
    std::string NumStr;
    CleanLiteral(Tok, NumStr);
    E = CharacterConstantExpr::Create(Context, getTokenRange(),
                                      StringRef(NumStr), Context.CharacterTy);
    ConsumeToken();
    // Possible substring
    if(IsPresent(tok::l_paren))
      return ParseSubstring(E);
    break;
  }
  case tok::int_literal_constant: {
    std::string NumStr;
    CleanLiteral(Tok, NumStr);

    StringRef Data(NumStr);
    std::pair<StringRef, StringRef> StrPair = Data.split('_');
    E = IntegerConstantExpr::Create(Context, getTokenRange(),
                                    StrPair.first);
    SetKindSelector(cast<ConstantExpr>(E.get()), StrPair.second);

    Lex();
    break;
  }
  case tok::real_literal_constant: {
    std::string NumStr;
    CleanLiteral(Tok, NumStr);

    StringRef Data(NumStr);
    std::pair<StringRef, StringRef> StrPair = Data.split('_');
    E = RealConstantExpr::Create(Context, getTokenRange(),
                                 NumStr, Context.RealTy);
    SetKindSelector(cast<ConstantExpr>(E.get()), StrPair.second);
    ConsumeToken();
    break;
  }
  case tok::double_precision_literal_constant: {
    std::string NumStr;
    CleanLiteral(Tok, NumStr);
    // Replace the d/D exponent into e exponent
    for(size_t I = 0, Len = NumStr.length(); I < Len; ++I) {
      if(NumStr[I] == 'd' || NumStr[I] == 'D') {
        NumStr[I] = 'e';
        break;
      } else if(NumStr[I] == '_') break;
    }

    StringRef Data(NumStr);
    std::pair<StringRef, StringRef> StrPair = Data.split('_');
    E = RealConstantExpr::Create(Context, getTokenRange(),
                                 NumStr, Context.DoublePrecisionTy);
    SetKindSelector(cast<ConstantExpr>(E.get()), StrPair.second);
    ConsumeToken();
    break;
  }
  case tok::identifier:
    possible_keyword_as_ident:
    E = Parser::ParseDesignator(IsLvalue);
    if (E.isInvalid()) return E;
    break;
  case tok::minus:
    Lex();
    E = Parser::ParsePrimaryExpr();
    if (E.isInvalid()) return E;
    E = Actions.ActOnUnaryExpr(Context, Loc, UnaryExpr::Minus, E);
    break;
  case tok::plus:
    Lex();
    E = Parser::ParsePrimaryExpr();
    if (E.isInvalid()) return E;
    E = Actions.ActOnUnaryExpr(Context, Loc, UnaryExpr::Plus, E);
    break;
  }

  return E;
}
Example #22
0
int FAO::Compute()
{
	ExprAST * tree = ParseExpression();
	return tree->GetValue();
}
Example #23
0
const char* RegExp::ParseFactor(StrPP& factor)
{
  StrPP tmp;
  factor = "";

  switch(reExpression[0])
  {
    case LPAREN:			// ( - parenthesised expression
      reExpression++;
      ParseExpression(tmp);
      factor += tmp;
      if(reExpression != RPAREN)
	return(NULL);
      reExpression++;
      break;

    case CCL:				// [ - character class; Ex: [0-9]
      reExpression++;
      ParseCCL(tmp);
      factor += tmp;
      if(reExpression != CCLEND)
	return(NULL);
      reExpression++;
      break;

    case ANY:				// .
    case EOL:				// $
      factor += reExpression[0];
      reExpression++;
      break;

    case ESCAPE :			// \
      reExpression++;
      factor += LITCHAR;
      factor += ParseEscape();
      reExpression++;
      break;

    case CLOSURE:			// *
    case POS_CLO:			// +
    case ZERO_ONE:			// ?
    case NEGATE:			// ^
    case CCLEND:			// ]
    case RPAREN:			// )
    case OR:				// |
      return(NULL);			// not valid characters

    default:				// literal character
      factor += LITCHAR;
      factor += reExpression[0];
      reExpression++;
      break;
  }

  if(reExpression == CLOSURE  ||	// check for closure
     reExpression == ZERO_ONE ||
     reExpression == POS_CLO)
  {
    if(ParseClosure(factor) == _RE_FALSE_)
      return(NULL);
  }
  return factor;
}
/* returnexpr
 * */
static shared_ptr<ExprAST> ParseReturnExpr() {
    getNextToken();//eat return
    return shared_ptr<ExprAST>(new ReturnAST(ParseExpression()));
}
Example #25
0
TExpressionPtr ExpressionParser::ParseOperationExpression(StringPtrLen str) const
{
   BracketsBalancer balancer;
   auto max_operation = OperationType::None;
   auto max_operation_amount = -1L;
   auto tail = str;

   // Find operation with zero bracket balance and with maximum value.
   // Maximum value means minimal arithmetic priority.
   for (; tail.Len() > 0; tail.RemoveLeft(1))
   {
      if (!balancer.ProcessChar(tail.At(0)) && balancer.GetBalance() == 0)
      {
         OperationType operation = StartsWithOperation(tail);
         // TODO: Skip the whole operation symbols
         if (operation != OperationType::None)
         {
            if (operation > max_operation)
            {
               max_operation = operation;
               max_operation_amount = 1;
            }
            else if (operation == max_operation)
            {
               ++max_operation_amount;
            }
         }
      }
   }

   if (OperationType::None == max_operation)
   {
      // No operations with zero balance
      return TExpressionPtr();
   }

   assert(balancer.GetBalance() == 0);

   auto max_operation_str = OperationTypeToString(max_operation);
   auto max_operation_str_len = std::strlen(max_operation_str);

   if (OperationType::Negation == max_operation)
   {
      if (!str.StartsWith(max_operation_str))
      {
         Error("Incorrect usage of unary operation '", max_operation_str, "'.");
      }

      str.RemoveLeft(max_operation_str_len);
      auto child_expression = ParseExpression(str);
      return std::make_unique<OperationExpression>(std::move(child_expression));
   }

   TExpressionPtrVector children_expressions;
   children_expressions.reserve(max_operation_amount + 1);

   tail = str;
   while (tail.Len() > 0)
   {
      if (!balancer.ProcessChar(tail.At(0)) && balancer.GetBalance() == 0)
      {
         if (tail.StartsWith(max_operation_str))
         {
            auto child_expression = ParseExpression(str.Left(tail.Ptr()));
            children_expressions.push_back(std::move(child_expression));
            tail.RemoveLeft(max_operation_str_len);
            str = tail;
            continue;
         }
      }
      tail.RemoveLeft(1);
   }

   auto child_expression = ParseExpression(str);
   children_expressions.push_back(std::move(child_expression));

   return std::make_unique<OperationExpression>(max_operation, std::move(children_expressions));
}
Example #26
0
void TParser::ParseCASE(void)
{
    TCaseItem *pCaseItemList;   // ptr to list of CASE items
    int        caseBranchFlag;  // true if another CASE branch,
				//   else false

    pCaseItemList = NULL;

    //--Append placeholders for the location of the token that
    //--follows the CASE statement and of the CASE branch table.
    //--Remember the locations of these placeholders.
    int atFollowLocationMarker      = PutLocationMarker();
    int atBranchTableLocationMarker = PutLocationMarker();

    //--<expr>
    GetTokenAppend();
    TType *pExprType = ParseExpression()->Base();

    //--Verify the type of the CASE expression.
    if (   (pExprType != pIntegerType)
	&& (pExprType != pCharType)
	&& (pExprType->form != fcEnum)) {
	Error(errIncompatibleTypes);
    }

    //--OF
    Resync(tlOF, tlCaseLabelStart);
    CondGetTokenAppend(tcOF, errMissingOF);

    //--Loop to parse CASE branches.
    caseBranchFlag = TokenIn(token, tlCaseLabelStart);
    while (caseBranchFlag) {
	if (TokenIn(token, tlCaseLabelStart)) {
	    ParseCaseBranch(pExprType, pCaseItemList);
	}

	if (token == tcSemicolon) {
	    GetTokenAppend();
	    caseBranchFlag = true;
	}
	else if (TokenIn(token, tlCaseLabelStart)) {
	    Error(errMissingSemicolon);
	    caseBranchFlag = true;
	}
	else caseBranchFlag = false;
    }

    //--Append the branch table to the intermediate code.
    FixupLocationMarker(atBranchTableLocationMarker);
    TCaseItem *pItem = pCaseItemList;
    TCaseItem *pNext;
    do {
	PutCaseItem(pItem->labelValue, pItem->atBranchStmt);
	pNext = pItem->next;
	delete pItem;
	pItem = pNext;
    } while (pItem);
    PutCaseItem(0, 0);  // end of table

    //--END
    Resync(tlEND, tlStatementStart);
    CondGetTokenAppend(tcEND, errMissingEND);
    FixupLocationMarker(atFollowLocationMarker);
}
Example #27
0
/* =====================================================
 * Write down the code needed to call COMPARATOR(...)
 *  ===================================================== */
void CallComponent(PARSER_CONFIG* conf, CSV_INPUT *data, FILE *flp, int nLn)
{
	int i = 0;
	int ret = 0;
	int nIO = 0;
	EXPRESSION expr;
	bool foundComp = false;

	int nInp = 0, nOut = 0;

	COMPONENT comp;

        fprintf(stderr, " MakeComponentCall: \n");
        fprintf(stderr, " MakeComponentCall: nom_row = %d\n", data->nom_row);
        fprintf(stderr, " MakeComponentCall: Id_compon = %d\n", data->Id_compon);
        fprintf(stderr, " MakeComponentCall: page_alg = %s\n", data->page_alg);
        fprintf(stderr, " MakeComponentCall: Type_compon = %s\n", data->Type_compon);
        fprintf(stderr, " MakeComponentCall: run_compon = %s\n", data->run_compon);
        fprintf(stderr, " MakeComponentCall: data_struct = %s\n", data->data_struct);
        fprintf(stderr, " MakeComponentCall: description = %s\n", data->description);
        fprintf(stderr, " MakeComponentCall: comments = %s\n", data->comments);
        fprintf(stderr, "\n");	

	fprintf(stderr, "nComp = %d\n", conf->nComp);

	// Fill component name and data structure name
	
	// We're going through preconfigured components one by one, 
	// checking radiy's native names against the one given on CSV-data
	
	for (int i = 0; i < conf->nComp; i++)
	{

		
		fprintf(stderr, "%d: %s <-> %s\n", i, data->run_compon, conf->comp[i].radiyName);
		
		// "It's a kind of magic"(c) - we found what we need
		// Now let's fill local COMPONENT buffer with component's info
		// from configuration structure so we can use it for writing the code
		if (!strcmp(data->run_compon, conf->comp[i].radiyName))
		{
			memcpy((char*)&comp, (char*)&(conf->comp[i]), sizeof(COMPONENT));
			foundComp = true;
			conf->comp[i].nFound++;	// increment number of found components 
			break;
		}
	}

	if (!foundComp)
	{
		// Put a note into cscan code
		fprintf(flp, "\n\n/* Warning: component type %s mentioned in line %d not found in configuration*/\n\n", data->run_compon, data->nom_row);
		// And drop the same line into a log or onto a screen
		fprintf(stderr, "\n\n/* Warning: component type %s mentioned in line %d not found in configuration*/\n\n", data->run_compon, data->nom_row);
		// Sorry, done
		return;
	}	
	
	// Put cleanup statement in front of component call
	
	fprintf(flp, "\tmemset(&%s, \'\\x0\', sizeof(%s));\n\n", comp.datastructName, comp.datatypeName);
		

	// Loop through all arguments, expressions are expected
	
	//////////////////////////////////////////////////////
	//  This is output loop
	//////////////////////////////////////////////////////
	i = 0;
	while (strlen(data->args[i]))
	{

		fprintf(stderr, "MakeComponentCall: args[%d] = %s\n", i, data->args[i]);

		ret = ParseExpression(data->args[i], &expr);	

		fprintf(stderr, "\nInput loop EXPRESSION: ret = %d\n", ret);
		fprintf(stderr, "signal = %d\n", expr.signal);
		fprintf(stderr, "number = %d\n", expr.number);
		fprintf(stderr, "list = %d\n", expr.list);
		fprintf(stderr, "error = %d\n", expr.error);
		fprintf(stderr, "lp = %s\n", expr.lp);
		fprintf(stderr, "rp = %s\n", expr.rp);
		fprintf(stderr, "mddname = %s\n", expr.mddname);
		fprintf(stderr, "inMDD = %d\\nn", expr.inMDD);

		if (ret == IAM_EXPRESSION)
		{
			//fprintf(flp, "/* Original: %s*/ \n", data->args[i]);

			// Here we make two loops through comp's IO array - the 1st one in serch of inputs, 
			// the 2nd one in search of outputs
			
			// Get all inputs 1st
			
			nIO = 0;
			while (strlen(comp.inputNames[nIO]))
			{
					
				if (!strcmp(comp.inputNames[nIO], expr.lp))
				{
	                       		if (expr.signal) // mdd name appears on the right
					{
						if (expr.rp[0] == '!')
							GetSignalInfo(nLn, expr.rp + 1, expr.mddname);	 // function will update nSig and fill *(signals + nSig)
						else
							GetSignalInfo(nLn, expr.rp, expr.mddname);	 // function will update nSig and fill *(signals + nSig)

						
	
						if ((signals + nSig - 1)->found)
							fprintf(flp, "\t// Internal ID: %s    External ID: %s\n", (signals + nSig - 1)->radiyname, 
								(signals + nSig - 1)->extID);
						/*
						fprintf(flp, "\t// Coordinates: %s\n", (signals + nSig - 1)->coord); 
						fprintf(flp, "\t// Descrption: %s\n", (signals + nSig - 1)->descr); 
						}*/
						if (expr.Not) // all that inputIsArray staff is a f*****g patch - force RADIY to get rid of that shit!!
						{
							//if ((comp.inputIsArray) && (!strcmp(comp.inputNames[nIO], "XIN")))  // PATCH!!!! 
							if (comp.inputIsArray[nIO]) 
	                                			fprintf(flp, "\t%s.%s[0] = !%s;\t// PATCH %s\n", comp.datastructName, expr.lp, expr.mddname, comp.inputDesc[nIO]);
							else
	                                			fprintf(flp, "\t%s.%s = !%s;\t// %s\n", comp.datastructName, expr.lp, expr.mddname, comp.inputDesc[nIO]);

						}
						else
						{
							//if ((comp.inputIsArray) && (!strcmp(comp.inputNames[nIO], "XIN")))  // PATCH!!!! 
							if (comp.inputIsArray[nIO]) 
	                                			fprintf(flp, "\t%s.%s[0] = %s;\t// PATCH %s\n", comp.datastructName, expr.lp, expr.mddname, comp.inputDesc[nIO]);
							else
	                                			fprintf(flp, "\t%s.%s = %s;\t// %s\n", comp.datastructName, expr.lp, expr.mddname, comp.inputDesc[nIO]);
						}

						strcpy(data->inputs[nInp], expr.rp );
						nInp++;

					}
	                        	else if (expr.number) // right part appears on the right as is 
					{	
	                                	fprintf(flp, "\t%s.%s = %s;\t// %s\n", comp.datastructName, expr.lp, expr.rp, comp.inputDesc[nIO]);
						strcpy(data->inputs[nInp], expr.rp );
						nInp++;
					}
					else if (expr.list) // we have a coma-sep list on the right. 
							    // Let's parse it and print as lp[n] = ... 
					{

	                                			fprintf(flp, "\t// %s\n", comp.inputDesc[nIO]);
								ParseVarList(nLn, flp, comp.datastructName, expr.lp, expr.rp);	

								int nLst = 0;
								while (strlen(inputsLst[nLst]))
								{
									strcpy(data->inputs[nInp], inputsLst[nLst]);
									nInp++;
									nLst++;
								}


					}
				}

				nIO++;
			}

		}
		else 
			fprintf(flp, "/*Not a valid expression: %s*/ \n", data->args[i]);
		
		i++;
	}

	// Write a component call as all inputs are set

	fprintf(flp, "\n\t%s(&%s);\n\n", comp.simexecName, comp.datastructName);

	//////////////////////////////////////////////////////
	//  This is output loop, exactly the same as the one 
	//  for inputs above
	//////////////////////////////////////////////////////
	i = 0;
        while (strlen(data->args[i]))
        {

                ret = ParseExpression(data->args[i], &expr);

                if (ret == IAM_EXPRESSION)
                {
                        //fprintf(flp, "/* Original: %s*/ \n", data->args[i]);

                        // Here we make two loops through comp's IO array - the 1st one in serch of inputs,
                        // the 2nd one in search of outputs
                        
                        // Get all outputs now 
                        nIO = 0;
                        while (strlen(comp.outputNames[nIO]))
                        {
                        	if (!strcmp(comp.outputNames[nIO], expr.lp))
                        	{
                        		if (expr.signal) // mdd name appears on the left, that's fine
					{
						if (expr.rp[0] == '!')
							GetSignalInfo(nLn, expr.rp + 1, expr.mddname);       // function will update nSig and fill *(signals + nSig)
						else
							GetSignalInfo(nLn, expr.rp, expr.mddname);       // function will update nSig and fill *(signals + nSig)

                        			if ((signals + nSig - 1)->found)
                        				fprintf(flp, "\t// Internal ID: %s    External ID: %s\n", (signals + nSig - 1)->radiyname,
                        						(signals + nSig - 1)->extID);
						/*
						fprintf(flp, "\t// Coordinates: %s\n", (signals + nSig - 1)->coord);
						fprintf(flp, "\t// Descrption: %s\n", (signals + nSig - 1)->descr);
						*/
						if (expr.Not)
                        				fprintf(flp, "\t%s = !%s.%s;\t//%s\n", expr.mddname, comp.datastructName, expr.lp,  comp.outputDesc[nIO]);
						else
                        				fprintf(flp, "\t%s = %s.%s;\t//%s\n", expr.mddname, comp.datastructName, expr.lp, comp.outputDesc[nIO]);

						strcpy(data->outputs[nOut], expr.rp );
						nOut++;

					}
                        		else if (expr.number) // This is error - invalid left part of the equation
					{
                        			fprintf(flp, "\t/* Error, wrong LP: %s = %s.%s;*/ \n", expr.rp, comp.datastructName, expr.lp);
						strcpy(data->outputs[nOut], expr.rp );
						nOut++;
					}
                        	}

                                nIO++;
                        }
                }
                else
                        fprintf(flp, "/*Not a valid expression: %s*/ \n", data->args[i]);

                i++;
        }

	fprintf(flp, "\n\n");

	return;
}
//==========================================================================
//
// ParseStates
// parses a state block
//
//==========================================================================
int ParseStates(FActorInfo * actor, AActor * defaults, Baggage &bag)
{
	FString statestring;
	intptr_t count = 0;
	FState state;
	FState * laststate = NULL;
	intptr_t lastlabel = -1;
	int minrequiredstate = -1;

	SC_MustGetStringName ("{");
	SC_SetEscape(false);	// disable escape sequences in the state parser
	while (!SC_CheckString ("}") && !sc_End)
	{
		memset(&state,0,sizeof(state));
		statestring = ParseStateString();
		if (!statestring.CompareNoCase("GOTO"))
		{
do_goto:	
			statestring = ParseStateString();
			if (SC_CheckString ("+"))
			{
				SC_MustGetNumber ();
				statestring += '+';
				statestring += sc_String;
			}
			// copy the text - this must be resolved later!
			if (laststate != NULL)
			{ // Following a state definition: Modify it.
				laststate->NextState = (FState*)copystring(statestring);	
			}
			else if (lastlabel >= 0)
			{ // Following a label: Retarget it.
				RetargetStates (count+1, statestring);
			}
			else
			{
				SC_ScriptError("GOTO before first state");
			}
		}
		else if (!statestring.CompareNoCase("STOP"))
		{
do_stop:
			if (laststate!=NULL)
			{
				laststate->NextState=(FState*)-1;
			}
			else if (lastlabel >=0)
			{
				RetargetStates (count+1, NULL);
			}
			else
			{
				SC_ScriptError("STOP before first state");
				continue;
			}
		}
		else if (!statestring.CompareNoCase("WAIT") || !statestring.CompareNoCase("FAIL"))
		{
			if (!laststate) 
			{
				SC_ScriptError("%s before first state", sc_String);
				continue;
			}
			laststate->NextState=(FState*)-2;
		}
		else if (!statestring.CompareNoCase("LOOP"))
		{
			if (!laststate) 
			{
				SC_ScriptError("LOOP before first state");
				continue;
			}
			laststate->NextState=(FState*)(lastlabel+1);
		}
		else
		{
			const char * statestrp;

			SC_MustGetString();
			if (SC_Compare (":"))
			{
				laststate = NULL;
				do
				{
					lastlabel = count;
					AddState(statestring, (FState *) (count+1));
					statestring = ParseStateString();
					if (!statestring.CompareNoCase("GOTO"))
					{
						goto do_goto;
					}
					else if (!statestring.CompareNoCase("STOP"))
					{
						goto do_stop;
					}
					SC_MustGetString ();
				} while (SC_Compare (":"));
//				continue;
			}

			SC_UnGet ();

			if (statestring.Len() != 4)
			{
				SC_ScriptError ("Sprite names must be exactly 4 characters\n");
			}

			memcpy(state.sprite.name, statestring, 4);
			state.Misc1=state.Misc2=0;
			state.ParameterIndex=0;
			SC_MustGetString();
			statestring = (sc_String+1);
			statestrp = statestring;
			state.Frame=(*sc_String&223)-'A';
			if ((*sc_String&223)<'A' || (*sc_String&223)>']')
			{
				SC_ScriptError ("Frames must be A-Z, [, \\, or ]");
				state.Frame=0;
			}

			SC_MustGetNumber();
			sc_Number++;
			state.Tics=sc_Number&255;
			state.Misc1=(sc_Number>>8)&255;
			if (state.Misc1) state.Frame|=SF_BIGTIC;

			while (SC_GetString() && !sc_Crossed)
			{
				if (SC_Compare("BRIGHT")) 
				{
					state.Frame|=SF_FULLBRIGHT;
					continue;
				}
				if (SC_Compare("OFFSET"))
				{
					if (state.Frame&SF_BIGTIC)
					{
						SC_ScriptError("You cannot use OFFSET with a state duration larger than 254!");
					}
					// specify a weapon offset
					SC_MustGetStringName("(");
					SC_MustGetNumber();
					state.Misc1=sc_Number;
					SC_MustGetStringName (",");
					SC_MustGetNumber();
					state.Misc2=sc_Number;
					SC_MustGetStringName(")");
					continue;
				}

				// Make the action name lowercase to satisfy the gperf hashers
				strlwr (sc_String);

				int minreq=count;
				if (DoActionSpecials(state, !statestring.IsEmpty(), &minreq, bag))
				{
					if (minreq>minrequiredstate) minrequiredstate=minreq;
					goto endofstate;
				}

				PSymbol *sym = bag.Info->Class->Symbols.FindSymbol (FName(sc_String, true), true);
				if (sym != NULL && sym->SymbolType == SYM_ActionFunction)
				{
					PSymbolActionFunction *afd = static_cast<PSymbolActionFunction *>(sym);
					state.Action = afd->Function;
					if (!afd->Arguments.IsEmpty())
					{
						const char *params = afd->Arguments.GetChars();
						int numparams = (int)afd->Arguments.Len();
				
						int v;

						if (!islower(*params))
						{
							SC_MustGetStringName("(");
						}
						else
						{
							if (!SC_CheckString("(")) goto endofstate;
						}
						
						int paramindex = PrepareStateParameters(&state, numparams);
						int paramstart = paramindex;
						bool varargs = params[numparams - 1] == '+';

						if (varargs)
						{
							StateParameters[paramindex++] = 0;
						}

						while (*params)
						{
							switch(*params)
							{
							case 'I':
							case 'i':		// Integer
								SC_MustGetNumber();
								v=sc_Number;
								break;

							case 'F':
							case 'f':		// Fixed point
								SC_MustGetFloat();
								v=fixed_t(sc_Float*FRACUNIT);
								break;


							case 'S':
							case 's':		// Sound name
								SC_MustGetString();
								v=S_FindSound(sc_String);
								break;

							case 'M':
							case 'm':		// Actor name
							case 'T':
							case 't':		// String
								SC_SetEscape(true);
								SC_MustGetString();
								SC_SetEscape(false);
								v = (int)(sc_String[0] ? FName(sc_String) : NAME_None);
								break;

							case 'L':
							case 'l':		// Jump label

								if (SC_CheckNumber())
								{
									if (strlen(statestring)>0)
									{
										SC_ScriptError("You cannot use A_Jump commands with a jump index on multistate definitions\n");
									}

									v=sc_Number;
									if (v<1)
									{
										SC_ScriptError("Negative jump offsets are not allowed");
									}

									{
										int minreq=count+v;
										if (minreq>minrequiredstate) minrequiredstate=minreq;
									}
								}
								else
								{
									if (JumpParameters.Size()==0) JumpParameters.Push(NAME_None);

									v = -(int)JumpParameters.Size();
									// This forces quotation marks around the state name.
									SC_MustGetToken(TK_StringConst);
									FString statestring = sc_String; // ParseStateString();
									const PClass *stype=NULL;
									int scope = statestring.IndexOf("::");
									if (scope >= 0)
									{
										FName scopename = FName(statestring, scope, false);
										if (scopename == NAME_Super)
										{
											// Super refers to the direct superclass
											scopename = actor->Class->ParentClass->TypeName;
										}
										JumpParameters.Push(scopename);
										statestring = statestring.Right(statestring.Len()-scope-2);

										stype = PClass::FindClass (scopename);
										if (stype == NULL)
										{
											SC_ScriptError ("%s is an unknown class.", scopename.GetChars());
										}
										if (!stype->IsDescendantOf (RUNTIME_CLASS(AActor)))
										{
											SC_ScriptError ("%s is not an actor class, so it has no states.", stype->TypeName.GetChars());
										}
										if (!stype->IsAncestorOf (actor->Class))
										{
											SC_ScriptError ("%s is not derived from %s so cannot access its states.",
												actor->Class->TypeName.GetChars(), stype->TypeName.GetChars());
										}
									}
									else
									{
										// No class name is stored. This allows 'virtual' jumps to
										// labels in subclasses.
										// It also means that the validity of the given state cannot
										// be checked here.
										JumpParameters.Push(NAME_None);
									}
									TArray<FName> names;
									MakeStateNameList(statestring, &names);

									if (stype != NULL)
									{
										if (!stype->ActorInfo->FindState(names.Size(), &names[0]))
										{
											SC_ScriptError("Jump to unknown state '%s' in class '%s'",
												statestring.GetChars(), stype->TypeName.GetChars());
										}
									}
									JumpParameters.Push((ENamedName)names.Size());
									for(unsigned i=0;i<names.Size();i++)
									{
										JumpParameters.Push(names[i]);
									}
									// No offsets here. The point of jumping to labels is to avoid such things!
								}

								break;

							case 'C':
							case 'c':		// Color
								SC_MustGetString ();
								if (SC_Compare("none"))
								{
									v = -1;
								}
								else
								{
									int c = V_GetColor (NULL, sc_String);
									// 0 needs to be the default so we have to mark the color.
									v = MAKEARGB(1, RPART(c), GPART(c), BPART(c));
								}
								break;

							case 'X':
							case 'x':
								v = ParseExpression (false, bag.Info->Class);
								break;

							case 'Y':
							case 'y':
								v = ParseExpression (true, bag.Info->Class);
								break;

							default:
								assert(false);
								v = -1;
								break;
							}
							StateParameters[paramindex++] = v;
							params++;
							if (varargs)
							{
								StateParameters[paramstart]++;
							}
							if (*params)
							{
								if (*params == '+')
								{
									if (SC_CheckString(")"))
									{
										goto endofstate;
									}
									params--;
									v = 0;
									StateParameters.Push(v);
								}
								else if ((islower(*params) || *params=='!') && SC_CheckString(")"))
								{
									goto endofstate;
								}
								SC_MustGetStringName (",");
							}
						}
						SC_MustGetStringName(")");
					}
					else 
					{
						SC_MustGetString();
						if (SC_Compare("("))
						{
							SC_ScriptError("You cannot pass parameters to '%s'\n",sc_String);
						}
						SC_UnGet();
					}
					goto endofstate;
				}
				SC_ScriptError("Invalid state parameter %s\n", sc_String);
			}
			SC_UnGet();
endofstate:
			StateArray.Push(state);
			while (*statestrp)
			{
				int frame=((*statestrp++)&223)-'A';

				if (frame<0 || frame>28)
				{
					SC_ScriptError ("Frames must be A-Z, [, \\, or ]");
					frame=0;
				}

				state.Frame=(state.Frame&(SF_FULLBRIGHT|SF_BIGTIC))|frame;
				StateArray.Push(state);
				count++;
			}
			laststate=&StateArray[count];
			count++;
		}
	}
	if (count<=minrequiredstate)
	{
		SC_ScriptError("A_Jump offset out of range in %s", actor->Class->TypeName.GetChars());
	}
	SC_SetEscape(true);	// re-enable escape sequences
	return count;
}
Example #29
0
/* modified */
int GetBytes(char*& p, int e[], int add, int dc) {
	aint val;
	int t = 0;
	while ('o') {
		SkipBlanks(p);
		if (!*p) {
			Error("Expression expected", 0, SUPPRESS); break;
		}
		if (t == 128) {
			Error("Too many arguments", p, SUPPRESS); break;
		}
		if (*p == '"') {
			p++;
			do {
				if (!*p || *p == '"') {
					Error("Syntax error", p, SUPPRESS); e[t] = -1; return t;
				}
				if (t == 128) {
					Error("Too many arguments", p, SUPPRESS); e[t] = -1; return t;
				}
				GetCharConstChar(p, val); check8(val); e[t++] = (val + add) & 255;
			} while (*p != '"');
			++p; if (dc && t) {
				 	e[t - 1] |= 128;
				 }
			/* (begin add) */
		} else if ((*p == 0x27) && (!*(p+2) || *(p+2) != 0x27)) {
		  	p++;
			do {
				if (!*p || *p == 0x27) {
					Error("Syntax error", p, SUPPRESS);
					e[t] = -1;
					return t;
				}
				if (t == 128) {
		  			Error("Too many arguments", p, SUPPRESS);
					e[t] = -1;
					return t;
				}
		  		GetCharConstCharSingle(p, val);
				check8(val);
				e[t++] = (val + add) & 255;
			} while (*p != 0x27);

		  	++p;

			if (dc && t) {
				e[t - 1] |= 128;
			}
		  	/* (end add) */
		} else {
			if (ParseExpression(p, val)) {
				check8(val); e[t++] = (val + add) & 255;
			} else {
				Error("Syntax error", p, SUPPRESS);
				break;
			}
		}
		SkipBlanks(p);
		if (*p != ',') {
			break;
		}
		++p;
	}
	e[t] = -1;
	return t;
}
Example #30
0
SymVar* Parser::ParseDeclarator(SymType* type, bool parseParams)
{
    SymVar* result = NULL;

    //pointer
    while (*lexer.Peek() == MULTIPLICATION)
    {
        type = new SymTypePointer(type);
        lexer.Get();
    }

    //direct-declarator
    if (*lexer.Peek() == ROUND_LEFT_BRACKET)
    {
        lexer.Get();
        result =  ParseDeclarator(type);
        Expected(lexer.Get()->GetSubType(), ROUND_RIGHT_BRACKET);
        return result;
    }

    Expected(parseParams || *lexer.Peek() == IDENTIFIER, "exepcted an identifier");

    if (parseParams && *lexer.Peek() != IDENTIFIER)
    {
        string n = to_string((long double)counter++);
        BaseToken* dummy = new BaseToken("abstract-"+n, 0, 0, IDENTIFIER, IDENTIFIER);
        result = new SymVar(dummy, type);
    }
    else
    {
        string msg = "redefinition: " + lexer.Peek()->GetText();
        Expected(!symStack.Top()->Find(lexer.Peek()->GetText()), &msg[0]);
        result = new SymVar(lexer.Get(), type);
    }

    BaseToken* token = lexer.Peek();
    if (*token == SQUARE_LEFT_BRACKET)
    {
        lexer.Get();
        Expected(*lexer.Peek() != SQUARE_RIGHT_BRACKET, "unknown size");

        SyntaxNode* index = ParseExpression();
        Expected(*index->token != IDENTIFIER, "expression must have a constant value");

        SymType* indexType = index->GetType();
        Expected(indexType == intType && indexType->CanConvertTo(intType),
                 "expression must be an integral constant expression");

        Expected(lexer.Get()->GetSubType(), SQUARE_RIGHT_BRACKET);

        int size = dynamic_cast<TokenVal <int> *>(index->token)->GetValue();
        result->SetType(new SymTypeArray(size, type));
    }
    else if (*token == ROUND_LEFT_BRACKET)
    {
        lexer.Get();
        SymTypeFunc* t = new SymTypeFunc(type);
        t->params->offset = 4;

        symStack.Push(t->params);
        ParseParameterList();
        symStack.Pop();

        if (*lexer.Peek() == FIGURE_LEFT_BRACKET)
        {
            parseFunc.push_back(t);
            t->body = ParseBlock();
            parseFunc.pop_back();
        }
        result->SetType(t);
    }

    return result;
}