TEST_F(FloatingPoint, AddTwoImmediateDouble)
        {
            auto setup = GetSetup();

            {
                Function<double> expression(setup->GetAllocator(), setup->GetCode());

                double immediate1 = 123.0;
                double immediate2 = 0.456;
                auto & a = expression.Immediate(immediate1);
                auto & b = expression.Immediate(immediate2);
                auto & c = expression.Add(a, b);
                auto function = expression.Compile(c);


                auto expected = immediate1 + immediate2;
                auto observed = function();

                ASSERT_EQ(observed, expected);
            }
        }
Example #2
0
NodePointer Parser::statement()
{
	NodePointer result;

	switch (currentSymbol_.symbolType_)
	{
		case IF:
			return ifStatement();

		case WHILE:
			return whileStatement();

		case IDENTIFIER:
		case GLOBAL:
		case ARGUMENT:
		case CALL:
		case CONSTANT:
			result = expression();
			accept(SEMICOLON);
			return result;

		case MY:
			return localVariable();

		case PRINT:
			return printStatement();

		case SUBROUTINE:
			return procedureDefinition();

		case RETURN:
			return returnStatement();

		case LEFT_BRACE:
			return blockStatement();

		default:
			throw ErrorMessage("Unexpected symbol " + symbolToString(currentSymbol_), getLineNumber());
	}
}
Example #3
0
char    *factor(void)
{
    char *tempvar=NULL;
    char *temp;
    if( match(ID) )
    {
	/* Print the assignment instruction. The %0.*s conversion is a form of
	 * %X.Ys, where X is the field width and Y is the maximum number of
	 * characters that will be printed (even if the string is longer). I'm
	 * using the %0.*s to print the string because it's not \0 terminated.
	 * The field has a default width of 0, but it will grow the size needed
	 * to print the string. The ".*" tells printf() to take the maximum-
	 * number-of-characters count from the next argument (yyleng).
	 */
        //printf("MOV %0.*s, %s\n",  yyleng, yytext ,tempvar=newname());
        fprintf(f,"MOVB %0.*s, %s \n",  yyleng, yytext ,tempvar=newname());
        temp = current_lexeme();
        add_to_table(temp);
        free(temp);
        advance();
    }
    else if (match(NUM)){
    	//printf("MOV $%0.*s, %s\n",  yyleng, yytext ,tempvar=newname());
        fprintf(f,"MOVB $%0.*s, %s\n",  yyleng, yytext ,tempvar=newname());
        advance();
    }
    else if( match(LP) )
    {
        advance();
        tempvar = expression();
        if( match(RP) )
            advance();
        else
            fprintf(stderr, "%d: Mismatched parenthesis\n", yylineno );
    }
    else
	fprintf( stderr, "%d: Number or identifier expected\n", yylineno );

    return tempvar;
}
Example #4
0
SNODE    *retstmt(void) 
/*
 * Handle return 
 */
{       SNODE    *snp; 
				TYP *tp;
        snp = xalloc(sizeof(SNODE)); 
				snp->next = 0;
        snp->stype = st_return; 
				snp->exp = 0;
        getsym(); 
				if (lastst == end || lastst == semicolon) {
					if (currentfunc->tp->btp->type != bt_void)
						generror(ERR_RETMISMATCH,0,0);
					needpunc(semicolon,0);
				}
				else {
					int ogc = goodcode;
					goodcode |= GF_SUPERAND;
        	tp = expression(&(snp->exp));
					goodcode = ogc;
        	if( lastst != eof)
                needpunc( semicolon, 0 );
					if (tp->type == bt_void) {
						generror(ERR_NOVOIDRET,0,0);
					}
					else
/*						if (tp->type == bt_pointer && tp->val_flag)
							generror(ERR_NOFUNCARRAY,0,0);
						else
*/						if (!checktype(tp,currentfunc->tp->btp))
								if (isscalar(tp) && isscalar(currentfunc->tp->btp))
									promote_type(currentfunc->tp->btp, &(snp->exp));
								else
									if (currentfunc->tp->btp->type != bt_pointer ||
											floatrecurse(snp->exp))
										generror(ERR_RETMISMATCH,0,0);
				}
        return snp; 
} 
Example #5
0
static sl_node_base_t*
statement(sl_parse_state_t* ps)
{
    sl_node_base_t* node;
    switch(peek_token(ps)->type) {
        case SL_TOK_CLOSE_TAG:
            next_token(ps);
            node = inline_raw(ps);
            if(peek_token(ps)->type != SL_TOK_END) {
                expect_token(ps, SL_TOK_OPEN_TAG);
            }
            return node;
        case SL_TOK_SEMICOLON:
            next_token(ps);
            return NULL;
        case SL_TOK_IF:
        case SL_TOK_UNLESS:
            return if_expression(ps);
        case SL_TOK_SWITCH:
            return switch_expression(ps);
        case SL_TOK_FOR:
            return for_expression(ps);
        case SL_TOK_WHILE:
        case SL_TOK_UNTIL:
            return while_expression(ps);
        case SL_TOK_DEF:
            return def_expression(ps);
        case SL_TOK_CLASS:
            return class_expression(ps);
        default:
            node = expression(ps);
            if(peek_token(ps)->type != SL_TOK_CLOSE_TAG
                && peek_token(ps)->type != SL_TOK_CLOSE_BRACE
                && token(ps)->type != SL_TOK_CLOSE_BRACE
                && peek_token(ps)->type != SL_TOK_END) {
                expect_token(ps, SL_TOK_SEMICOLON);
            }
            return node;
    }
}
Example #6
0
AST* Parser::callExpression(Scope* ps)
{
    Position begin = lex_->peek().range_.begin_;

    AST* expr = primary(ps);

    for (;;)
    {
        if (expect("."))
        {
            match(".");
            Identifier* mem = identifier(ps);
            Position end = lex_->peek().range_.begin_;
            expr = new ObjectMember(PositionRange(begin, end), expr, mem);
            expr->scope_ = ps;
        }
        else if (expect("("))
        {
            auto args = arglist(ps);
            Position end = lex_->peek().range_.begin_;
            expr = new Call(PositionRange(begin, end), expr, args);
            expr->scope_ = ps;
        }
        else if (expect("["))
        {
            match("[");
            AST* key = expression(0, ps);
            match("]");
            Position end = lex_->peek().range_.begin_;
            expr = new ArrayMember(PositionRange(begin, end), expr, key);
            expr->scope_ = ps;
        }
        else
        {
            break;
        }
    }

    return expr;
}
Example #7
0
 void Parser::relation() 
 {
     expression();
     if (Cradle::isRelOp(input.getChar())) {
         output.emitLine("MOVE D0,(SP)-");
         switch (input.getChar()) {
             case '=':
                 equals();
                 break;
             case '#':
                 notEquals();
                 break;
             case '<':
                 lessThan();
                 break;
             case '>':
                 greaterThan();
                 break;
         }
         output.emitLine("TST D0");
     }
 }
double primary()
// deal with numbers and parentheses
{
    Token t = ts.get();
    switch (t.kind) {
    case '(':    // handle '(' expression ')'
        {    
            double d = expression();
            t = ts.get();
            if (t.kind != ')') error("')' expected");
            return d;
        }
    case number:            // we use '8' to represent a number
        return t.value;  // return the number's value
    case '-':
		return - primary();
	case '+':
		return primary();
    default:
        error("primary expected");
    }
}
Example #9
0
AbstractProperty BindingProperty::resolveToProperty() const
{
    if (!isValid())
        throw InvalidModelNodeException(__LINE__, __FUNCTION__, __FILE__);

    QString binding = expression();
    ModelNode node = parentModelNode();
    QString element;
    if (binding.contains(QLatin1Char('.'))) {
        element = binding.split(QLatin1Char('.')).last();
        QString nodeBinding = binding;
        nodeBinding.chop(element.length());
        node = resolveBinding(nodeBinding, parentModelNode(), view());
    } else {
        element = binding;
    }

    if (node.isValid())
        return node.property(element);
    else
        return AbstractProperty();
}
Example #10
0
void QScriptHighlighter::highlightBlock(const QString & txt)
{
	for(const HighlightingRule & rule : highlightingRules)
	{
		QRegExp expression(rule.pattern);
		int index = expression.indexIn(txt);
        
		while(index >= 0)
		{
			const int length = expression.matchedLength();
			setFormat(index, length, rule.format);
			index = expression.indexIn(txt, index + length);
        }
    }
	
	setCurrentBlockState(0);

    int startIndex = 0;

	if(previousBlockState() != 1)
		startIndex = commentStartExpression.indexIn(txt);
	
	while(startIndex >= 0)
	{
		int endIndex = commentEndExpression.indexIn(txt, startIndex);
		int commentLength;
		
		if(endIndex == -1)
		{
			setCurrentBlockState(1);
			commentLength = txt.length() - startIndex;
		}
		else
			commentLength = endIndex - startIndex + commentEndExpression.matchedLength();

		setFormat(startIndex, commentLength, multiLineCommentFormat);
		startIndex = commentStartExpression.indexIn(txt, startIndex + commentLength);
    }
}
Example #11
0
// Partition function based on the Lomuto's Partitioning Algorithm
static int partition(T* vector, int left, int right, comparation(*expression)(T, T))
{
	// Pick a random pivot index and select the pivot item
	int pivot_index = left + (rand() % (right - left + 1));
	T pivot = vector[pivot_index];

	swap_by_pointers(vector + pivot_index, vector + right);
	pivot_index = right;
	int i = left - 1, j;

	for (j = left; j < right; j++)
	{
		comparation result = expression(vector[j], pivot);
		if (result == LOWER || result == EQUAL)
		{
			i++;
			swap_by_pointers(vector + i, vector + j);
		}
	}
	swap_by_pointers(vector + i + 1, vector + pivot_index);
	return i + 1;
}
void classeSurligneur::highlightBlock(const QString &text)
{
	QTextCharFormat formatTexte;
	formatTexte.setBackground(Qt::yellow);
	QString texteRecherche(fenetrePrincipale->zoneTexteRechercheDansArticle->currentText());

	if (texteRecherche.isEmpty() == false) {
		const Qt::CaseSensitivity respecterCasse(Qt::CaseSensitivity(
				fenetrePrincipale->actionRespecterCasse->isChecked()));
		const QRegExp::PatternSyntax syntaxe(fenetrePrincipale->
				actionEmployerExpressionRationnelle->isChecked()
				? QRegExp::RegExp : QRegExp::FixedString);
		QRegExp expression(texteRecherche, respecterCasse, syntaxe);

		int nombreIndex(text.indexOf(expression));
		while (nombreIndex >= 0) {
			const int nombreLongueur(expression.matchedLength());
			setFormat(nombreIndex, nombreLongueur, formatTexte);
			nombreIndex = text.indexOf(expression, nombreIndex + nombreLongueur);
		}
	}
}
Example #13
0
TreeNode* if_stmt(void)
{
    TreeNode* t = newStmtNode(IfK);

    match(IF);
    if (t != NULL)
        t->child[0] = expression();

    match(THEN);
    if (t != NULL)
        t->child[1] = stmt_sequence();

    if (s_token == ELSE)
    {
        match(ELSE);
        if (t != NULL)
            t->child[2] = stmt_sequence();
    }

    match(END);
    return t;
}
Example #14
0
void SignalFrame::insert( std::vector<std::string>& input )
{
  // extract:   variable_name:type=value   or   variable_name:array[type]=value1,value2
  boost::regex expression(  "([[:word:]]+)(\\:([[:word:]]+)(\\[([[:word:]]+)\\])?=(.*))?"  );
  boost::match_results<std::string::const_iterator> what;

  boost_foreach (const std::string& arg, input)
  {

    std::string name;
    std::string type;
    std::string subtype; // in case of array<type>
    std::string value;

    if (regex_search(arg,what,expression))
    {
      name=what[1];
      type=what[3];
      subtype=what[5];
      value=what[6];

      //CFinfo << name << ":" << type << (subtype.empty() ? std::string() : std::string("["+subtype+"]"))  << "=" << value << CFendl;

      if(type == "array")
      {
        set_array(name, subtype, value, " ; ");
      }
      else
      {
        set_option(name, type, value);
      }
    }
    else
      throw ParsingFailed(FromHere(), "Could not parse [" + arg + "].\n"+
                          "Format should be:\n"
                          " -  for simple types:  variable_name:type=value\n"
                          " -  for array types:   variable_name:array[type]=value1,value2\n"
                          "  with possible type: [bool,unsigned,integer,real,string,uri]");
  }
Example #15
0
Node* RegroupNodeFactory::getNode( const QString &tagContent, Parser *p ) const
{
  QStringList expr = tagContent.split( QLatin1Char( ' ' ) );

  if ( expr.size() != 6 ) {
    throw Grantlee::Exception( TagSyntaxError, QLatin1String( "widthratio takes five arguments" ) );
  }
  FilterExpression target( expr.at( 1 ), p );
  if ( expr.at( 2 ) != QLatin1String( "by" ) ) {
    throw Grantlee::Exception( TagSyntaxError, QLatin1String( "second argument must be 'by'" ) );
  }

  if ( expr.at( 4 ) != QLatin1String( "as" ) ) {
    throw Grantlee::Exception( TagSyntaxError, QLatin1String( "fourth argument must be 'as'" ) );
  }

  FilterExpression expression( QLatin1String( "\"" ) + expr.at( 3 ) + QLatin1String( "\"" ), p );

  QString name = expr.at( 5 );

  return new RegroupNode( target, expression, name, p );
}
QString VariableController::expressionUnderCursor(KTextEditor::Document* doc, const KTextEditor::Cursor& cursor)
{
    QString line = doc->line(cursor.line());
    int index = cursor.column();
    QChar c = line[index];
    if (!c.isLetterOrNumber() && c != '_' && c != '$')
        return QString();

    int start = Utils::expressionAt(line, index);
    int end = index;
    for (; end < line.size(); ++end) {
        QChar c = line[end];
        if (!(c.isLetterOrNumber() || c == '_' || c == '$'))
            break;
    }
    if (!(start < end))
        return QString();

    QString expression(line.mid(start, end-start));
    expression = expression.trimmed();
    return expression;
}
Example #17
0
void pas_RepeatStatement ()
{
   uint16_t rpt_label = ++label;

   TRACE(lstFile,"[pas_RepeatStatement]");

   /* REPEAT <statement[;statement[statement...]]> UNTIL <expression> */

   /* Generate top of loop label */

   pas_GenerateDataOperation(opLABEL, rpt_label);
   do
     {
       getToken();

       /* Process <statement> */

       statement();
     }
   while (token == ';');

   /* Verify UNTIL follows */

   if (token !=  tUNTIL) error (eUNTIL);
   else getToken();

   /* Generate UNTIL <expression> */

   expression(exprBoolean, NULL);

   /* Generate conditional branch to the top of loop */

   pas_GenerateDataOperation(opJEQUZ, rpt_label);

   /* NOTE:  The current LSP setting will be correct after the repeat
    * loop because we fall through from the bottom of the loop after
    * executing the body at least once.
    */
}
Example #18
0
//Produção Factor
ExpressionNode* factor(){
    printf("Factor\n");                
       if (lookahead == ID ){
           int fIdIndex = retornaIndiceLexemaAtual();
           REGISTRO *fregi = retornaRegistroAtual();
           IdNode* fId = new IdNode(fIdIndex,fregi);
           match(ID,followFactor, &fIdIndex);
           return factorLinha(fId);
       }else if (lookahead == NOT ){
           match(NOT,followFactor, NULL);
           return new NotNode(factor());
       }else if (lookahead == NUM ){
           int fNumIndex = retornaIndiceLexemaAtual();
           match(NUM,followFactor, &fNumIndex);
           return new NumberNode(fNumIndex, retornaRegistroAtual());
       }else if (lookahead == OPENPAR ){
           match(OPENPAR,followFactor, NULL);
           ExpressionNode* expreP = expression();
           match(CLOSEPAR,followFactor, NULL);
           return expreP;
       }else {emiteErroSintatico(ERRO_TOKEN_INVALIDO,lookahead,retornaLinha()); return NULL;}
}
Example #19
0
void DocxZipHandler::scanimage() {


    QString html = HTMLSTREAM;
    HTMLSTREAM.clear();
    QByteArray docindex = docitem("word/_rels/document.xml.rels");
    QRegExp expression("src=[\"\'](.*)[\"\']", Qt::CaseInsensitive);
    expression.setMinimal(true);
    int iPosition = 0;
    while ((iPosition = expression.indexIn(html, iPosition)) != -1) {
        const QString imagesrcx = expression.cap(1); /// this must replaced
        int loengh = imagesrcx.length();
        int repos = imagesrcx.indexOf("=");
        /// nul pixel __ONEPIXELGIF__
        BASICDOCDEBUG() << "HTML image found Docx:" << imagesrcx;
        if (repos > 0) {
            const QString key = imagesrcx.mid(repos + 1, loengh - (repos - 1)).simplified();
            QString imagechunker = read_docx_index(docindex, 1, key);
            if (!imagechunker.isEmpty()) {
                html.replace(imagesrcx, imagechunker);
                //// BASICDOCDEBUG() << "HTML image found Docx:" << imagesrcx;
                //// BASICDOCDEBUG() << "HTML image found Docx:" << key;
            } else {
                BASICDOCDEBUG() << "HTML image insert null pixel :" << imagesrcx;
               html.replace(imagesrcx,__ONEPIXELGIF__); 
            }
        } else {
           html.replace(imagesrcx,__ONEPIXELGIF__); 
        }
        iPosition += expression.matchedLength();
    }

    ////QTextDocument *doc = new QTextDocument();
    ///doc->setHtml(html);
    /////html.clear(); doc->toHtml("utf-8"); 
    html.replace("&#10; ", "");
    HTMLSTREAM = html.simplified();
    html.clear();
}
Example #20
0
void ch2()
{
	printf("==========ch2()\n");
	// float PI3.14159;  // 非法标识符,内含小数点,非数字、字母、下划线,因此非法 
	ch2_1();
	ch2_2();
	ch2_3();
	ch2_4();
	ch2_5();
	ch2_6();
	ch2_7();
	ch2_8();
	floatTest();
	doubleTest();
	testAdd1();
	testAdd2();
	testAdd3();
	testprintf();
	test_and_or();
	expression();
	//getchar();
}
Example #21
0
 expression operator()(
     const Left &, const Right &,
     typename boost::enable_if<
     boost::mpl::and_<
     type_traits::meta::is_promotable< Left >,
     type_traits::meta::is_promotable< Right >
     >
     >::type* = 0
 ) const {
     const auto converted = usual_arithmetic_conversion( context, ir_builder, left, right );
     const std::shared_ptr< llvm::LLVMContext > &context_ = context;
     return expression(
                converted.first.type(), converted.first.llvm_type(),
                std::shared_ptr< llvm::Value >(
                    ir_builder->CreateOr(
                        converted.first.llvm_value().get(),
                        converted.second.llvm_value().get()
                    ),
     [context_]( llvm::Value* ) {}
                )
            );
 }
static exprType absFunc(void)
{
   exprType absType;

   TRACE(lstFile,"[absFunc]");

   /* FORM:  ABS (<simple integer/real expression>) */

   checkLParen();

   absType = expression(exprUnknown, NULL);
   if (absType == exprInteger)
      pas_GenerateSimple(opABS);
   else if (absType == exprReal)
      pas_GenerateFpOperation(fpABS);
   else
      error(eINVARG);

   checkRParen();
   return absType;

} /* end absFunc */
Example #23
0
/* selection-stmt -> 
 * if (expression) statement [else statement]*/
static TreeNode * selection_stmt (void)
{ TreeNode * t = NULL;

  while (token == COMMENT) unexpectedTokenHandling();
  if (token == IF)
  { t = newStmtNode (IfK);
    match (IF);
    match (LPAREN);
    if (t != NULL)
      t->child[0] = expression();
    match (RPAREN);
    if (t != NULL)
      t->child[1] = statement();
    /* [else statement] */
    if (token == ELSE)
    { match (ELSE);
      if (t != NULL)
        t->child[2] = statement();
    }
  }
  return t;
}
Example #24
0
NodePointer Parser::ifStatement()
{
	accept(IF);
	accept(LEFT_PARENTHESIS);
	NodePointer expressionTree = expression();
	accept(RIGHT_PARENTHESIS);
	NodePointer blockStatementTree = blockStatement();
	NodePointer elseStatementTree;
	if (currentSymbol_.symbolType_ == ELSIF)
	{
		// nasty trick splitting 'elsif' into 'else if'
		currentSymbol_.symbolType_ = IF;
		elseStatementTree = ifStatement();
	}
	else if (currentSymbol_.symbolType_ == ELSE)
	{
		getNextSymbol();
		elseStatementTree = blockStatement();
	}
	NodePointer ifStatementTree(new IfStatement(expressionTree, blockStatementTree, elseStatementTree));
	return ifStatementTree;
}
Example #25
0
void statement()
{
	if(syn==10)      //字母
	{
		scaner();
		if(syn==18)  //'='
		{
			scaner();
			expression();
		}
		else
		{
			kk=1;
			return;
		}
	}
	else
	{
		kk=1;
		return;
	}
}
Example #26
0
Statement *ParseWhileStatement() 
{       
	Statement *snp;

	currentFn->UsesPredicate = TRUE;
    snp = NewStatement(st_while, TRUE);
	snp->predreg = iflevel;
	iflevel++;
    if( lastst != openpa ) 
        error(ERR_EXPREXPECT); 
    else { 
        NextToken(); 
        if( expression(&(snp->exp)) == 0 ) 
            error(ERR_EXPREXPECT); 
        needpunc( closepa ); 
		if (lastst==kw_do)
			NextToken();
        snp->s1 = ParseStatement(); 
    } 
	iflevel--;
    return snp; 
} 
Example #27
0
 expression operator()(
   const Left &, const Right &,
   typename boost::enable_if<
     type_traits::meta::is_arithmetic_convertible< Left, Right >
   >::type* = 0
 ) const {
   const auto result_type = get_type< bool >();
   const auto converted_left = implicit_cast( context, ir_builder, result_type, left );
   const auto converted_right = implicit_cast( context, ir_builder, result_type, right );
   const std::shared_ptr< llvm::LLVMContext > &context_ = context;
   const auto llvm_type = get_llvm_type( context, result_type );
   return expression(
     result_type, llvm_type,
     std::shared_ptr< llvm::Value >(
       ir_builder->CreateOr(
         converted_left.llvm_value().get(),
         converted_right.llvm_value().get()
       ),
       [context_]( llvm::Value* ){}
     )
   );
 }
Example #28
0
Ast::UnaryOp* Parser::primary()
{
    ++current;
    switch(current->type) {
        case TokenType::String:
            return new Ast::UnaryOp(new Ast::Literal(Variable(current->getValue<Variable::StringType>())));
        case TokenType::Number:
            return new Ast::UnaryOp(new Ast::Literal(Variable(current->getValue<Variable::NumberType>())));
        case TokenType::Article:
            // We actually expect another primary now
            // because we allow an optional article before a primary
            return primary();
        case TokenType::Identifier:
            return new Ast::UnaryOp(new Ast::VarNode(current->getValue<std::string>(), &data_handler));
        case TokenType::FuncResult:
            skipOptional(TokenType::Of);
            ++current;
            if(current->type == TokenType::Identifier && current->getValue<std::string>() == "calling");
                ++current;

            return new Ast::UnaryOp(handleFunctionCall());
        case TokenType::Operator: {
            char op = current->getValue<char>();
            if(op == '(') {
                Ast::UnaryOp* uop = new Ast::UnaryOp(expression());
                ++current;
                if(current->getValue<char>() != ')')
                    error("expected ')' after '('", current->line);
                return uop;
            } else if(op == '-')
                return new Ast::UnaryOp(primary(), op);
            else
                error("unexpected operator in primary", current->line);
        }
        default:
            error("primary expected", current->line);
    }
    return nullptr;
}
Example #29
0
void Debugger::showValue (void) {

	getToken();

	if (curToken == TKN_SEMICOLON)
			print("Bad Expression.\n");
	else {
		//------------------------------------------------------------
		// NOTE: Need a SOFT FATAL for parsing expressions here so the
		// debugger's errors don't Fatal out of the game!
		//------------------------------------------------------------

		//---------------------------------------------------------------
		// It's important that the expression parser return an error code
		// rather than fatal!
		TypePtr typePtr = expression();
		if (errorCount > 0)
			return;
			
		char* savedCodeSegmentPtr = codeSegmentPtr;
		TokenCodeType savedCodeToken = codeToken;
		execExpression();

		if (typePtr->form == FRM_ARRAY) {
			print("SHOW ARRAY\n");
			}
		else {
			char message[255];
			sprintDataValue(message, tos, typePtr);
			strcat(message, "\n");
			print(message);
		}

		pop();
		codeSegmentPtr = savedCodeSegmentPtr;
		codeToken = savedCodeToken;
	}

}
static int factor (void)
{
  int r;
  switch (tokenizer_token())
  {
    case T_NUMBER:
      r = tokenizer_num();
      accept(T_NUMBER);
      break;
    case T_LEFT_PAREN:
      accept(T_LEFT_PAREN);
      r = expression();
      accept(T_RIGHT_PAREN);
      break;
    default:
      r = get_variable(
        tokenizer_variable_num());
      accept(T_LETTER);
      break;
  }
  return r;
}