Пример #1
0
//all input instructions are assumed to be valid.
//i.e. sytactically correct and no illegal operations
//(e.g. division by zero)
//variables may not start with digits
//variables are assumed to be integers
int main(){
    char curr_var[MAX_VAR_IDENT_LENGTH];
    char curr_operator;
    char curr_operand[MAX_VAR_IDENT_LENGTH];

    /*Input from file for testing purposes
    FILE *fin;
    if( (fin = fopen("in.txt","r")) == NULL){
        printf("file not found\n");
        exit(1);
    }
    fscanf(fin,"%s",inst);
    */

    /*input from keyboard*/
    scanf("%s",inst);
    /**/

    instIndex = 0;
    int instLen = strlen(inst)-1;

    while(instIndex<instLen){
        readVariable(curr_var);
        readOperator(&curr_operator);
        readOperand(curr_operand);
        compute(curr_var, curr_operator, curr_operand);
    }

    printVars();

    return 0;
}
Пример #2
0
NimLexer::Token NimLexer::onDefaultState()
{
    while (!m_stream->isEnd())
    {
        if (isSkipChar(m_stream)) {
            m_stream->move();
            continue;
        }
        if (isOperator(m_stream))
            return readOperator(m_stream);
        if (matchDocumentationStart(m_stream))
            return readDocumentation(m_stream);
        if (matchCommentStart(m_stream))
            return readComment(m_stream);
        if (matchMultiLineStringLiteralStart(m_stream))
            return readMultiLineStringLiteral(m_stream, true);
        if (matchStringLiteralStart(m_stream))
            return readStringLiteral(m_stream);
        if (matchIdentifierOrKeywordStart(m_stream))
            return readIdentifierOrKeyword(m_stream);
        m_stream->move();
    }

    return Token {0,0, TokenType::EndOfText };
}
Пример #3
0
Файл: g7e4.c Проект: pingicx/cx
/*
Accepts a pointer to the array of floats containing the allocation for the operators,
a pointer to the operands and pointers to the variables "operator" and "error" initiated in main()
*/
void getInput(float numbers[], int *operator, int *error) {

	printf("Operator 1:\n");
	numbers[0] = readNumber(error);																		// First operand, calls with pointer to error to be able to update
																										// the error in main	
	printf("Operator 2:\n");	
	numbers[1] = readNumber(error);																		// Second operand. Same as first. checks for 0 division y zero here
	if ( !numbers[1] ) *error = 3;																		// for efficiency
	printf("(+) Sumar\n(-) Restar\n(*) Multiplicar\n(/) Dividir\n(^) XOR\n(&) AND\n(|) OR\n");
	*operator = readOperator(error);																	// Stores the value op readOperator
}
Пример #4
0
Token DefaultLexer::readToken() {
  char c = lookChar();

  while (true) {
    // skip whitespace
    while (isWhiteSpace(c)) {
      skipChar();
      c = lookChar();
    }

    // newlines
    if (isNewline(c)) {
      readNewline(c);
      if (interactive_ && getCurrentBraceNesting() == 0)
        return Token(TK_Newline);
      c = lookChar();
      continue;
    }

    // treat line comments as newlines
    if (c == '/' && lookChar(1) == '/') {
      readLineComment();
      c = lookChar();
      continue;
    }
    break;
  }

  SourceLocation sloc = getCurrentLocation();

  // punctuation
  if (c == '(') {
    skipChar();
    signalOpenBrace(TK_LParen);
    return Token(TK_LParen, "(", sloc);
  }
  if (c == ')') {
    skipChar();
    signalCloseBrace(TK_LParen);
    return Token(TK_RParen, ")", sloc);
  }
  if (c == '{') {
    skipChar();
    signalOpenBrace(TK_LCurlyBrace);
    return Token(TK_LCurlyBrace, "{", sloc);
  }
  if (c == '}') {
    skipChar();
    signalCloseBrace(TK_LCurlyBrace);
    return Token(TK_RCurlyBrace, "}", sloc);
  }
  if (c == '[') {
    skipChar();
    signalOpenBrace(TK_LSquareBrace);
    return Token(TK_LSquareBrace, "[", sloc);
  }
  if (c == ']') {
    skipChar();
    signalCloseBrace(TK_LSquareBrace);
    return Token(TK_RSquareBrace, "]", sloc);
  }
  if (c == ',') {
    skipChar();
    return Token(TK_Comma, ",", sloc);
  }
  if (c == ';') {
    skipChar();
    return Token(TK_Semicolon, ";", sloc);
  }
  if (c == ':' && !isOperatorChar(lookChar(1))) {
    skipChar();
    return Token(TK_Colon, ":", sloc);
  }
  if (c == '.') {
    skipChar();
    return Token(TK_Period, ".", sloc);
  }

  // identifiers
  if (isLetter(c)) {
    readIdentifier(c);
    StringRef str = copyStr(finishToken());

    unsigned keyid = lookupKeyword(str.c_str());
    if (keyid) {
      return Token(keyid, str, sloc);
    }
    return Token(TK_Identifier, str, sloc);
  }

  // generic operators
  if (isOperatorChar(c)) {
    readOperator(c);
    StringRef str = copyStr(finishToken());

    unsigned keyid = lookupKeyword(str.c_str());
    if (keyid) {
      return Token(keyid, str, sloc);
    }
    return Token(TK_Operator, str, sloc);
  }

  // numbers
  if (isDigit(c)) {
    readInteger(c);
    StringRef str = copyStr(finishToken());
    return Token(TK_LitInteger, str, sloc);
  }

  // characters
  if (c == '\'') {
    if (!readCharacter())
      return Token(TK_Error);

    StringRef str = copyStr(finishToken());
    return Token(TK_LitCharacter, str, sloc);
  }

  // strings
  if (c == '\"') {
    if (!readString())
      return Token(TK_Error);

    StringRef str = copyStr(finishToken());
    return Token(TK_LitString, str, sloc);
  }

  // if we're out of buffer, put in an EOF token.
  if (c == 0 || stream_eof()) {
    return Token(TK_EOF, "", sloc);
  }

  // Can't get the next token -- signal an error and bail.
  signalLexicalError();
  return Token(TK_Error, "", sloc);
}
Пример #5
0
static void findAsmTags (void)
{
    vString *name = vStringNew ();
    vString *operator = vStringNew ();
    const unsigned char *line;
    boolean inCComment = FALSE;

    while ((line = readLineFromInputFile ()) != NULL)
    {
        const unsigned char *cp = line;
        boolean labelCandidate = (boolean) (! isspace ((int) *cp));
        boolean nameFollows = FALSE;
        const boolean isComment = (boolean)
                                  (*cp != '\0' && strchr (";*@", *cp) != NULL);

        /* skip comments */
        if (strncmp ((const char*) cp, "/*", (size_t) 2) == 0)
        {
            inCComment = TRUE;
            cp += 2;
        }
        if (inCComment)
        {
            do
            {
                if (strncmp ((const char*) cp, "*/", (size_t) 2) == 0)
                {
                    inCComment = FALSE;
                    cp += 2;
                    break;
                }
                ++cp;
            } while (*cp != '\0');
        }
        if (isComment || inCComment)
            continue;

        /* read preprocessor defines */
        if (*cp == '#')
        {
            ++cp;
            readPreProc (cp);
            continue;
        }

        /* skip white space */
        while (isspace ((int) *cp))
            ++cp;

        /* read symbol */
        cp = readSymbol (cp, name);
        if (vStringLength (name) > 0  &&  *cp == ':')
        {
            labelCandidate = TRUE;
            ++cp;
        }

        if (! isspace ((int) *cp)  &&  *cp != '\0')
            continue;

        /* skip white space */
        while (isspace ((int) *cp))
            ++cp;

        /* skip leading dot */
#if 0
        if (*cp == '.')
            ++cp;
#endif

        cp = readOperator (cp, operator);

        /* attempt second read of symbol */
        if (vStringLength (name) == 0)
        {
            while (isspace ((int) *cp))
                ++cp;
            cp = readSymbol (cp, name);
            nameFollows = TRUE;
        }
        makeAsmTag (name, operator, labelCandidate, nameFollows);
    }
    vStringDelete (name);
    vStringDelete (operator);
}
Пример #6
0
void Operators::doOperator(Context *context, OperatorType oper) {
	Token token1, token2, token3;
	stutskFloat f1, f2;
	stutskInteger i1, i2;
	string s1, s2;

	switch (oper) {
	case OP_ASSIG:
		token1 = stack_back_safe();
		stutskStack.pop_back(); // Variable
		token2 = stack_back_safe();
		stutskStack.pop_back(); // Value
		setVariable(token1, token2); 
		break;
	case OP_ASSIG_REF:
		token1 = stack_back_safe();
		stutskStack.pop_back(); // Variable
		token2 = stack_back_safe();
		stutskStack.pop_back(); // Value
		setVariable(token1, token2, true); 
		break;
	case OP_FUNC:
		token1 = stack_back_safe();
		stutskStack.pop_back(); // Name
		token2 = stack_back_safe();
		stutskStack.pop_back(); // Codeblock
		recurseVariables(token2);
		if (token2.tokenType != T_CODEBLOCK) {
			throw StutskException(ET_ERROR, "Token is not a codeblock");
		}
		else {
			OperatorType dummy;
			string functionName = *giveString(token1);
			if (readOperator(functionName, dummy))
				throw StutskException(ET_ERROR, "Cannot override an operator");
			if (functionName.substr(0,10) == "__builtin_")
				throw StutskException(ET_ERROR, "Cannot override an internal function");
			userFunctions[functionName] = *token2.asTokenList;
		}

		break;
	case OP_UNSET:
		token1 = stack_back_safe();
		stutskStack.pop_back();
		if (token1.tokenType == T_VARIABLE) {
			struct Token::_un_TokenData::_un_VariableData *var = & token1.data.asVariable;
			TokenMap::iterator iter = var->context->variables.find(var->name);
			if (iter != var->context->variables.end())
				var->context->variables.erase(iter);
		}
		else {
			UserFunctionsMap::iterator iter = userFunctions.find(*giveString(token1));
			if (iter != userFunctions.end())
				userFunctions.erase(iter);
		}
		break;
	case OP_DEREF:
		token1 = stack_back_safe();
		stutskStack.pop_back();
		if (token1.tokenType != T_VARIABLE) {
			throw StutskException(ET_ERROR, "Token is not a variable");
		}
		else {
			recurseVariables(token1, true);
			stutskStack.push_back(copy_token(token1));
		}
		break;
	case OP_PLUSPLUS:
		token1 = stack_back_safe();
		stutskStack.pop_back(); // Name
		if (token1.tokenType == T_VARIABLE) {
			switch (giveGCD(token1, f1, i1, s1)) {
			case NT_INVALID:
			case NT_STRING:
				throw StutskException(ET_ERROR,
					"Variable is not a numeric type");
			case NT_INTEGER:
				token2.tokenType = T_INTEGER;
				token2.data.asInteger = i1 + 1;
				setVariable(token1, token2);
				break;
			case NT_FLOAT:
				token2.tokenType = T_FLOAT;
				token2.data.asFloat = f1 + 1.;
				setVariable(token1, token2); 
				break;
			}
		}
		else {
			switch (giveGCD(token1, f1, i1, s1)) {
			case NT_INVALID:
			case NT_STRING:
				throw StutskException(ET_ERROR, "Token is not a numeric type");
			case NT_INTEGER:
				pushInteger(++i1);
				break;
			case NT_FLOAT:
				pushFloat(++f1);
				break;
			}
		}
		break;
	case OP_MINMIN:
		token1 = stack_back_safe();
		stutskStack.pop_back(); // Name
		if (token1.tokenType == T_VARIABLE) {
			switch (giveGCD(token1, f1, i1, s1)) {
			case NT_INVALID:
			case NT_STRING:
				throw StutskException(ET_ERROR,
					"Variable is not a numeric type");
			case NT_INTEGER:
				token2.tokenType = T_INTEGER;
				token2.data.asInteger = i1 - 1;
				setVariable(token1, token2); 
				break;
			case NT_FLOAT:
				token2.tokenType = T_FLOAT;
				token2.data.asFloat = f1 - 1.;
				setVariable(token1, token2); 
				break;
			}
		}
		else {
			switch (giveGCD(token1, f1, i1, s1)) {
			case NT_INVALID:
			case NT_STRING:
				throw StutskException(ET_ERROR, "Token is not a numeric type");
			case NT_INTEGER:
				pushInteger(--i1);
				break;
			case NT_FLOAT:
				pushFloat(--f1);
				break;
			}
		}
		break;
	case OP_PLUS:
		token1 = stack_back_safe();
		stutskStack.pop_back();
		token2 = stack_back_safe();
		stutskStack.pop_back();

		switch (giveGCD(token1, f1, i1, s1)) {
		case NT_STRING:
		case NT_INVALID:
			throw StutskException(ET_ERROR, "Token is not a numeric type");
		case NT_INTEGER:
			switch (giveGCD(token2, f2, i2, s1)) {
			case NT_STRING:
			case NT_INVALID:
				throw StutskException(ET_ERROR, "Token is not a numeric type");
			case NT_INTEGER:
				i1 += i2;
				pushInteger(i1);
				break;
			case NT_FLOAT:
				f2 += i1;
				pushFloat(f2);
				break;
			}
			break;
		case NT_FLOAT:
			f1 += giveFloat(token2);
			pushFloat(f1);
			break;
		}

		break;
	case OP_MINUS:
		token1 = stack_back_safe();
		stutskStack.pop_back();
		token2 = stack_back_safe();
		stutskStack.pop_back();

		switch (giveGCD(token1, f1, i1, s1)) {
		case NT_STRING:
		case NT_INVALID:
			throw StutskException(ET_ERROR, "Token is not a numeric type");
		case NT_INTEGER:
			switch (giveGCD(token2, f2, i2, s1)) {
			case NT_STRING:
			case NT_INVALID:
				throw StutskException(ET_ERROR, "Token is not a numeric type");
			case NT_INTEGER:
				i2 -= i1;
				pushInteger(i2);
				break;
			case NT_FLOAT:
				f2 -= i1;
				pushFloat(f2);
				break;
			}
			break;
		case NT_FLOAT:
			f2 = giveFloat(token2) - f1;
			pushFloat(f2);
			break;
		}

		break;
	case OP_MULTIP:
		token1 = stack_back_safe();
		stutskStack.pop_back();
		token2 = stack_back_safe();
		stutskStack.pop_back();

		switch (giveGCD(token1, f1, i1, s1)) {
		case NT_STRING:
		case NT_INVALID:
			throw StutskException(ET_ERROR, "Token is not a numeric type");
		case NT_INTEGER:
			switch (giveGCD(token2, f2, i2, s1)) {
			case NT_STRING:
			case NT_INVALID:
				throw StutskException(ET_ERROR, "Token is not a numeric type");
			case NT_INTEGER:
				i1 *= i2;
				pushInteger(i1);
				break;
			case NT_FLOAT:
				f2 *= i1;
				pushFloat(f2);
				break;
			}
			break;
		case NT_FLOAT:
			f1 *= giveFloat(token2);
			pushFloat(f1);
			break;
		}
		break;
	case OP_DIV:
		token1 = stack_back_safe();
		stutskStack.pop_back();
		token2 = stack_back_safe();
		stutskStack.pop_back();

		switch (giveGCD(token1, f1, i1, s1)) {
		case NT_STRING:
		case NT_INVALID:
			throw StutskException(ET_ERROR, "Token is not a numeric type");
		case NT_INTEGER:
			if (i1 == 0)
				throw StutskException(ET_ERROR, "Division by zero");
			switch (giveGCD(token2, f2, i2, s1)) {
			case NT_STRING:
			case NT_INVALID:
				throw StutskException(ET_ERROR, "Token is not a numeric type");
			case NT_INTEGER:
				f1 = (stutskFloat)i2 / (stutskFloat)i1;
				pushFloat(f1);
				break;
			case NT_FLOAT:
				f2 /= (stutskFloat)i1;
				pushFloat(f2);
				break;
			}
			break;
		case NT_FLOAT:
			if (f1 == 0.)
				throw StutskException(ET_ERROR, "Division by zero");
			f2 = giveFloat(token2) / f1;
			pushFloat(f2);
			break;
		}
		break;
	case OP_DIVINT:
		token1 = stack_back_safe();
		stutskStack.pop_back();
		token2 = stack_back_safe();
		stutskStack.pop_back();

		switch (giveGCD(token1, f1, i1, s1)) {
		case NT_STRING:
		case NT_INVALID:
			throw StutskException(ET_ERROR, "Token is not a numeric type");
		case NT_INTEGER:
			switch (giveGCD(token2, f2, i2, s1)) {
			case NT_STRING:
			case NT_INVALID:
				throw StutskException(ET_ERROR, "Token is not a numeric type");
			case NT_INTEGER:
				i1 = (stutskInteger)i2 / i1;
				pushInteger(i1);
				break;
			case NT_FLOAT:
				i2 = (stutskInteger)f2 / i1;
				pushInteger(i2);
				break;
			}
			break;
		case NT_FLOAT:
			i2 = giveInteger(token2) / (stutskInteger)f1;
			pushInteger(i2);
			break;
		}
		break;
	case OP_MOD:
		token1 = stack_back_safe();
		stutskStack.pop_back();
		token2 = stack_back_safe();
		stutskStack.pop_back();

		switch (giveGCD(token1, f1, i1, s1)) {
		case NT_STRING:
		case NT_INVALID:
			throw StutskException(ET_ERROR, "Token is not a numeric type");
		case NT_INTEGER:
			switch (giveGCD(token2, f2, i2, s1)) {
			case NT_STRING:
			case NT_INVALID:
				throw StutskException(ET_ERROR, "Token is not a numeric type");
			case NT_INTEGER:
				i1 = (stutskInteger)i2 % i1;
				pushInteger(i1);
				break;
			case NT_FLOAT:
				i2 = (stutskInteger)f2 % i1;
				pushInteger(i2);
				break;
			}
			break;
		case NT_FLOAT:
			i2 = giveInteger(token2) % (stutskInteger)f1;
			pushInteger(i2);
			break;
		}
		break;
	case OP_LESSTHAN:
		token1 = stack_back_safe();
		stutskStack.pop_back();
		token2 = stack_back_safe();
		stutskStack.pop_back();

		pushBool(tokenNumericCompare(token1, token2) == CN_SMALLER);
		break;
	case OP_MORETHAN:
		token1 = stack_back_safe();
		stutskStack.pop_back();
		token2 = stack_back_safe();
		stutskStack.pop_back();

		pushBool(tokenNumericCompare(token1, token2) == CN_LARGER);
		break;
	case OP_LESSTHAN_EQ:
		token1 = stack_back_safe();
		stutskStack.pop_back();
		token2 = stack_back_safe();
		stutskStack.pop_back();

		pushBool(tokenNumericCompare(token1, token2) != CN_LARGER);
		break;
	case OP_MORETHAN_EQ:
		token1 = stack_back_safe();
		stutskStack.pop_back();
		token2 = stack_back_safe();
		stutskStack.pop_back();

		pushBool(tokenNumericCompare(token1, token2) != CN_SMALLER);
		break;
	case OP_EQ:
		token1 = stack_back_safe();
		stutskStack.pop_back();
		token2 = stack_back_safe();
		stutskStack.pop_back();

		pushBool(tokenEqual(token1, token2));	
		break;
	case OP_SAME:
		token1 = stack_back_safe();
		stutskStack.pop_back();
		token2 = stack_back_safe();
		stutskStack.pop_back();
		pushBool(tokenSame(token1, token2));
		break;
	case OP_NOTEQ:
		token1 = stack_back_safe();
		stutskStack.pop_back();
		token2 = stack_back_safe();
		stutskStack.pop_back();

		pushBool(!tokenEqual(token1, token2));	
		break;
	case OP_GLOBAL:
		token1 = stack_back_safe();
		stutskStack.pop_back(); // Variable
		if (token1.tokenType != T_VARIABLE) {
			throw StutskException(ET_ERROR, "Token is not a variable");
		}
		else {
			context->variableScopeMap[token1.data.asVariable.name] = VS_GLOBAL;
		}
		break;
	case OP_AUTO:
		token1 = stack_back_safe();
		stutskStack.pop_back(); // Variable
		if (token1.tokenType != T_VARIABLE) {
			throw StutskException(ET_ERROR, "Token is not a variable");
		}
		else {
			context->variableScopeMap[token1.data.asVariable.name] = VS_AUTO;
		}
		break;
	case OP_STATIC:
		token1 = stack_back_safe();
		stutskStack.pop_back(); // Variable
		if (token1.tokenType != T_VARIABLE) {
			throw StutskException(ET_ERROR, "Token is not a variable");
		}
		else {
			context->variableScopeMap[token1.data.asVariable.name] = VS_STATIC;
		}
		break;
	case OP_FOREVER:
		token1 = stack_back_safe();
		stutskStack.pop_back(); // Codeblock
		recurseVariables(token1);
		if (token1.tokenType != T_CODEBLOCK) {
			throw StutskException(ET_ERROR, "Token is not a codeblock");
		}
		else {
			while (true) {
				context->run(*token1.asTokenList, "forever");
				if (exitVar == OP_CONTINUE)
					exitVar = OP_INVALID;
				if (exitVar != OP_INVALID)
					break;
			}
			if (exitVar == OP_BREAK)
				exitVar = OP_INVALID;
		}
		break;
	case OP_FOREACH:
		token1 = stack_back_safe();
		stutskStack.pop_back(); // Codeblock
		token2 = stack_back_safe();
		stutskStack.pop_back(); // Codeblock

		recurseVariables(token1);
		if (token1.tokenType != T_CODEBLOCK)
			throw StutskException(ET_ERROR, "Token is not a codeblock");

		recurseVariables(token2);
		if (token2.tokenType == T_ARRAY) {
			for (TokenList::const_iterator it = token2.asTokenList->begin();
				it != token2.asTokenList->end(); ++it) {
					stutskStack.push_back(*it);
					stringstream ss;
					ss << "foreach [" << 
						std::distance(token2.asTokenList->cbegin(), it) << "]";
					context->run(*token1.asTokenList, ss.str());
					if (exitVar == OP_CONTINUE)
						exitVar = OP_INVALID;
					if (exitVar != OP_INVALID)
						break;
			}
		}
		else
			if (token2.tokenType == T_DICTIONARY) {
				for (TokenMap::const_iterator it = token2.asDictionary->begin();
					it != token2.asDictionary->end(); ++it) {
						stutskStack.push_back(it->second);
						StringPtr f = pushString();
						*f =  it->first;

						stringstream ss;
						ss << "foreach [" << it->first << "]";
						context->run(*token1.asTokenList, ss.str());
						if (exitVar == OP_CONTINUE)
							exitVar = OP_INVALID;
						if (exitVar != OP_INVALID)
							break;
				}
			}
			else 
			{
				StringPtr s1_ptr = giveString(token2);
				for (int i = 0; i < (signed)s1_ptr->length(); i++) {
					*pushString() = (*s1_ptr)[i];
					stringstream ss;
					ss << "foreach [" << i << "]";
					context->run(*token1.asTokenList, ss.str());
					if (exitVar == OP_CONTINUE)
						exitVar = OP_INVALID;
					if (exitVar != OP_INVALID)
						break;
				}
			}

			if (exitVar == OP_BREAK)
				exitVar = OP_INVALID;
			break;

	case OP_REPEAT:
		token1 = stack_back_safe();
		stutskStack.pop_back(); // Codeblock

		token2 = stack_back_safe();
		stutskStack.pop_back(); // Codeblock

		i1 = giveInteger(token2);
		recurseVariables(token1);

		if (token1.tokenType != T_CODEBLOCK) {
			throw StutskException(ET_ERROR, "Token is not a codeblock");
		}
		else {
			while (i1 > 0) {
				stringstream ss;
				ss << "repeat [" << i1 << "]";
				context->run(*token1.asTokenList, ss.str());
				if (exitVar == OP_CONTINUE)
					exitVar = OP_INVALID;
				if (exitVar != OP_INVALID)
					break;
				i1--;
			}
			if (exitVar == OP_BREAK)
				exitVar = OP_INVALID;
		}
		break;
	case OP_TRY:
		token1 = stack_back_safe();
		stutskStack.pop_back(); // Codeblock
		token2 = stack_back_safe();
		stutskStack.pop_back(); // Codeblock
		recurseVariables(token1);
		recurseVariables(token2);
		if ((token2.tokenType != T_CODEBLOCK) ||
			(token2.tokenType != T_CODEBLOCK)) {
				throw StutskException(ET_ERROR, "Token is not a codeblock");
		}
		else {
			try {
				context->run(*token2.asTokenList, "try");
			}
			catch (StutskException &e) {
				*pushString() = e.getMessage();
				pushInteger(e.getLineNumber());
				*pushString() = e.getFileName();

				context->run(*token1.asTokenList, "try");
			}
			catch (std::exception &e) {
				*pushString() = e.what();
				pushInteger(errorToken.lineNum);
				*pushString() = ParseContext::get_by_id(errorToken.context_id).FileName;

				context->run(*token1.asTokenList, "try");
			}
		}
		break;
	case OP_POWER:
		token1 = stack_back_safe();
		stutskStack.pop_back(); // Codeblock
		token2 = stack_back_safe();
		stutskStack.pop_back(); // Codeblock
		f1 = pow(giveFloat(token2), giveFloat(token1));
		pushFloat(f1);

		break;
	case OP_THROW:
		token1 = stack_back_safe();
		stutskStack.pop_back(); // Error name
		throw StutskException(ET_CUSTOM, *giveString(token1));
		break;
	case OP_NOT:
		token1 = stack_back_safe();
		stutskStack.pop_back();
		pushBool(!giveBool(token1));
		break;
	case OP_AND:
		token1 = stack_back_safe();
		stutskStack.pop_back();
		token2 = stack_back_safe();
		stutskStack.pop_back();
		pushBool(giveBool(token1) && giveBool(token2));
		break;
	case OP_OR:
		token1 = stack_back_safe();
		stutskStack.pop_back();
		token2 = stack_back_safe();
		stutskStack.pop_back();
		pushBool(giveBool(token1) || giveBool(token2));
		break;
	case OP_IF:
		token2 = stack_back_safe();
		stutskStack.pop_back(); // Codeblock
		token1 = stack_back_safe();
		stutskStack.pop_back(); // Codeblock

		recurseVariables(token2);

		if (token2.tokenType != T_CODEBLOCK) {
			throw StutskException(ET_ERROR, "Token is not a codeblock");
		}
		else {
			if (giveBool(token1)) {
				context->run(*token2.asTokenList, "if");
			}
		}
		break;
	case OP_IFELSE:
		token2 = stack_back_safe();
		stutskStack.pop_back(); // Codeblock
		token3 = stack_back_safe();
		stutskStack.pop_back(); // Codeblock
		token1 = stack_back_safe();
		stutskStack.pop_back(); // Codeblock

		recurseVariables(token2);
		recurseVariables(token3);

		if ((token2.tokenType != T_CODEBLOCK) ||
			(token3.tokenType != T_CODEBLOCK)) {
				throw StutskException(ET_ERROR, "Token is not a codeblock");
		}
		else {
			if (giveBool(token1)) {
				context->run(*token3.asTokenList, "ifelse");
			}
			else {
				context->run(*token2.asTokenList, "ifelse");
			}
		}
		break;
	case OP_TERNARY:
		token2 = stack_back_safe();
		stutskStack.pop_back(); // Codeblock
		token3 = stack_back_safe();
		stutskStack.pop_back(); // Codeblock
		token1 = stack_back_safe();
		stutskStack.pop_back(); // Codeblock

		stutskStack.push_back((giveBool(token1) ? token3 : token2));
		break;
	case OP_CONCAT:
		token1 = stack_back_safe();
		stutskStack.pop_back(); // Codeblock
		token2 = stack_back_safe();
		stutskStack.pop_back(); // Codeblock

		// Be careful NOT to recurse variable here because we wouldn't want
		// to overwrite the saved value.

		if (token2.tokenType == T_STRING) // Performance optimization
		{
			token2.asString->append(*giveString(token1));
			stutskStack.push_back(token2);
		}
		else
			// Should be fast enough ...	
			*pushString() = *giveString(token2) + 
			*giveString(token1);

		break;
	case OP_SWITCH:
		token2 = stack_back_safe();
		stutskStack.pop_back(); // Codeblock
		token1 = stack_back_safe();
		stutskStack.pop_back(); // Codeblock

		recurseVariables(token2);

		if (token2.tokenType != T_ARRAY)
			throw StutskException(ET_ERROR, "Token is not an array");
		else
		{	
			for (TokenList::iterator it = token2.asTokenList->begin();
				it != token2.asTokenList->end(); ++it) 
			{
				token3 = *it;
				recurseVariables(token3);
				if (token3.tokenType != T_ARRAY)
					throw StutskException(ET_ERROR, "Token is not an array");
				else
				{
					if (token3.asTokenList->size() != 2)
						throw StutskException(ET_ERROR, "Array of wrong length");
					if ((*token3.asTokenList)[1].tokenType != T_CODEBLOCK)
						throw StutskException(ET_ERROR, "Token is not a codeblock");
					if (tokenEqual(token1, (*token3.asTokenList)[0]))
					{
						context->run(*(*token3.asTokenList)[1].asTokenList, "switch");
						break;
					}
				}
			}
		}
		break;
	case OP_BREAK:
	case OP_CONTINUE:
	case OP_HALT:
	case OP_EXIT:
		exitVar = oper;
		break;
	case OP_ARRAY:
		token1 = stack_back_safe();
		stutskStack.pop_back(); // Codeblock
		token2 = stack_back_safe();
		stutskStack.pop_back(); // Codeblock

		recurseVariables(token1);

		if (token2.tokenType == T_VARIABLE) {
			if (token1.tokenType == T_ARRAY) {
				for (TokenList::iterator it = token1.asTokenList->begin();
					it != token1.asTokenList->end(); ++it)
					token2.index.push_back(giveInteger(*it));
			}
			else
				token2.index.push_back(giveInteger(token1));
			stutskStack.push_back(token2);
		}
		else if (token2.tokenType == T_ARRAY) {
			if (token1.tokenType == T_ARRAY) {
				for (TokenList::iterator it = token1.asTokenList->begin();
					it != token1.asTokenList->end(); ++it) {
						i1 = giveInteger(*it);
						if (i1 < 0)
							throw StutskException(ET_ERROR, "Array index underflow");
						if ((signed)token2.asTokenList->size() >= i1 + 1) {
							token2 = (*token2.asTokenList)[i1];
						}
						else
							throw StutskException(ET_ERROR, "Array index overflow");
				}
				stutskStack.push_back(token2);
			}
			else {
				i1 = giveInteger(token1);
				if (i1 < 0)
					throw StutskException(ET_ERROR, "Array index underflow");
				if ((signed)token2.asTokenList->size() >= i1 + 1) {
					stutskStack.push_back((*token2.asTokenList)[i1]);
				}
				else
					throw StutskException(ET_ERROR, "Array index overflow");
			}
		}
		else {
			i1 = giveInteger(token1);
			StringPtr s1_ptr = giveString(token2);
			if (i1 < 0)
				throw StutskException(ET_ERROR, "String index underflow");
			if ((signed)s1_ptr->length() >= i1 + 1) {
				*pushString() = (*s1_ptr)[i1];
			}
			else
				throw StutskException(ET_ERROR, "String index overflow");
		}
	}
}
Пример #7
0
Token Scanner::onDefaultState()
{
    QChar first = m_src.peek();
    m_src.move();

    // Ignore new lines
    bool hasNewLine = false;
    while (isLineFeed(first)) {
        hasNewLine = true;
        m_line++;
        m_lineStartOffset = m_src.position();
        first = m_src.peek();
        m_src.setAnchor();
        m_src.move();
    }
    if (hasNewLine)
        m_tokenSequence.clear();

    Token token;

    if (first.isDigit()) {
        token = readFloatNumber();
    } else if (first == '\'' || first == '\"' || first == '`') {
        token = readStringLiteral(first, State_String);
    } else if (m_methodPattern.match(m_tokenSequence).hasMatch()) {
        token = readMethodDefinition();
    } else if (first.isLetter() || first == '_' || first == '@'
               || first == '$' || (first == ':' && m_src.peek() != ':')) {
        token = readIdentifier();
    } else if (first.isDigit()) {
        token = readNumber();
    } else if (first == '#') {
        token = readComment();
    } else if (first == '/') {
        token = readRegexp();
    } else if (first.isSpace()) {
        token = readWhiteSpace();
    } else if (first == ',') {
        token = Token(Token::OperatorComma, m_src.anchor(), m_src.length());
    } else if (first == '.') {
        token = Token(Token::OperatorDot, m_src.anchor(), m_src.length());
    } else if (first == '=' && m_src.peek() != '=') {
        token = Token(Token::OperatorAssign, m_src.anchor(), m_src.length());
    } else if (first == ';') {
        token = Token(Token::OperatorSemiColon, m_src.anchor(), m_src.length());
    } else if (first == '%') {
        token = readPercentageNotation();
    } else if (first == '{') {
        token = Token(Token::OpenBraces, m_src.anchor(), m_src.length());
    } else if (first == '}') {
        token = Token(Token::CloseBraces, m_src.anchor(), m_src.length());
    } else if (first == '[') {
        token = Token(Token::OpenBrackets, m_src.anchor(), m_src.length());
    } else if (first == ']') {
        token = Token(Token::CloseBrackets, m_src.anchor(), m_src.length());
        // For historic reasons, ( and ) are the Operator token, this will
        // be changed soon.
    } else if (first == '(' || first == ')') {
        token = Token(Token::Operator, m_src.anchor(), m_src.length());
    } else {
        token = readOperator(first);
    }

    m_tokenSequence += QString::number(token.kind);
    m_tokenSequence += '_';

    return token;
}
Пример #8
0
static void findAsmTags (void)
{
	vString *name = vStringNew ();
	vString *operator = vStringNew ();
	const unsigned char *line;

	cppInit (false, false, false, false,
			 KIND_GHOST_INDEX, 0, KIND_GHOST_INDEX, 0, 0);

	unsigned int lastMacroCorkIndex = CORK_NIL;

	while ((line = asmReadLineFromInputFile ()) != NULL)
	{
		const unsigned char *cp = line;
		bool labelCandidate = (bool) (! isspace ((int) *cp));
		bool nameFollows = false;
		bool directive = false;
		const bool isComment = (bool)
				(*cp != '\0' && strchr (";*@", *cp) != NULL);

		/* skip comments */
		if (isComment)
			continue;

		/* skip white space */
		while (isspace ((int) *cp))
			++cp;

		/* read symbol */
		if (*cp == '.')
		{
			directive = true;
			labelCandidate = false;
			++cp;
		}

		cp = readSymbol (cp, name);
		if (vStringLength (name) > 0  &&  *cp == ':')
		{
			labelCandidate = true;
			++cp;
		}

		if (! isspace ((int) *cp)  &&  *cp != '\0')
			continue;

		/* skip white space */
		while (isspace ((int) *cp))
			++cp;

		/* skip leading dot */
#if 0
		if (*cp == '.')
			++cp;
#endif

		cp = readOperator (cp, operator);

		/* attempt second read of symbol */
		if (vStringLength (name) == 0)
		{
			while (isspace ((int) *cp))
				++cp;
			cp = readSymbol (cp, name);
			nameFollows = true;
		}
		makeAsmTag (name, operator, labelCandidate, nameFollows, directive,
					&lastMacroCorkIndex);
	}

	cppTerminate ();

	vStringDelete (name);
	vStringDelete (operator);
}