//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; }
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 }; }
/* 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 }
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); }
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); }
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"); } } }
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; }
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); }