diff --git a/common/libeval_compiler/grammar.lemon b/common/libeval_compiler/grammar.lemon
index ada6951462..99f107d94a 100644
--- a/common/libeval_compiler/grammar.lemon
+++ b/common/libeval_compiler/grammar.lemon
@@ -18,9 +18,11 @@
along with this program. If not, see .
*/
-%token_type { LIBEVAL::TREE_NODE }
+%token_type { LIBEVAL::T_TOKEN }
%extra_argument { LIBEVAL::COMPILER* pEval }
+%type nt {LIBEVAL::TREE_NODE*}
+
%nonassoc G_IDENTIFIER G_ASSIGN G_SEMCOL.
%left G_BOOL_AND.
%left G_BOOL_OR.
@@ -53,27 +55,131 @@ in ::= in stmt.
/* A statement can be empty, an expr or an expr followed by ';' */
stmt ::= G_ENDS.
-stmt ::= expr(A) G_ENDS. { pEval->setRoot(A); }
-//stmt ::= expr G_SEMCOL. { pEval->setRoot(NULL); }
+stmt ::= nt(A) G_ENDS. { pEval->setRoot(A); }
-expr(A) ::= G_VALUE(B). { A.op = TR_NUMBER; A.value = B.value; A.leaf[0] = A.leaf[1] = NULL; A.valid = true; A.srcPos = pEval->GetSourcePos(); }
-expr(A) ::= G_VALUE(B) G_UNIT(C). { A.op = TR_NUMBER; A.value = B.value; A.leaf[0] = newNode(TR_UNIT, C.value.type, ""); A.leaf[1] = NULL; A.valid = true; A.srcPos = pEval->GetSourcePos(); }
-expr(A) ::= G_STRING(B). { A.op = TR_STRING; A.value = B.value; A.leaf[0] = A.leaf[1] = NULL; A.valid = true; A.srcPos = pEval->GetSourcePos(); }
-expr(A) ::= G_IDENTIFIER(B). { A.op = TR_IDENTIFIER; A.value = B.value; A.leaf[0] = A.leaf[1] = NULL; A.valid = true; A.srcPos = pEval->GetSourcePos(); }
-expr(A) ::= expr(B) G_LESS_THAN expr(C). { A.op = TR_OP_LESS; A.value.wstr = NULL; A.leaf[0] = copyNode(B); A.leaf[1] = copyNode(C); A.valid = B.valid && C.valid; A.srcPos = pEval->GetSourcePos(); }
-expr(A) ::= expr(B) G_GREATER_THAN expr(C). { A.op = TR_OP_GREATER; A.value.wstr = NULL; A.leaf[0] = copyNode(B); A.leaf[1] = copyNode(C); A.valid = B.valid && C.valid; A.srcPos = pEval->GetSourcePos(); }
-expr(A) ::= expr(B) G_LESS_EQUAL_THAN expr(C). { A.op = TR_OP_LESS_EQUAL; A.value.wstr = NULL; A.leaf[0] = copyNode(B); A.leaf[1] = copyNode(C); A.valid = B.valid && C.valid; A.srcPos = pEval->GetSourcePos(); }
-expr(A) ::= expr(B) G_GREATER_EQUAL_THAN expr(C). { A.op = TR_OP_GREATER_EQUAL; A.value.wstr = NULL; A.leaf[0] = copyNode(B); A.leaf[1] = copyNode(C); A.valid = B.valid && C.valid; A.srcPos = pEval->GetSourcePos(); }
-expr(A) ::= expr(B) G_NOT_EQUAL expr(C). { A.op = TR_OP_NOT_EQUAL; A.value.wstr = NULL; A.leaf[0] = copyNode(B); A.leaf[1] = copyNode(C); A.valid = B.valid && C.valid; A.srcPos = pEval->GetSourcePos(); }
-expr(A) ::= expr(B) G_BOOL_AND expr(C). { A.op = TR_OP_BOOL_AND; A.value.wstr = NULL; A.leaf[0] = copyNode(B); A.leaf[1] = copyNode(C); A.valid = B.valid && C.valid; A.srcPos = pEval->GetSourcePos(); }
-expr(A) ::= expr(B) G_BOOL_OR expr(C). { A.op = TR_OP_BOOL_OR; A.value.wstr = NULL; A.leaf[0] = copyNode(B); A.leaf[1] = copyNode(C); A.valid = B.valid && C.valid; A.srcPos = pEval->GetSourcePos(); }
-expr(A) ::= expr(B) G_PLUS expr(C). { A.op = TR_OP_ADD; A.value.wstr = NULL; A.leaf[0] = copyNode(B); A.leaf[1] = copyNode(C); A.valid = B.valid && C.valid; A.srcPos = pEval->GetSourcePos(); }
-expr(A) ::= expr(B) G_MINUS expr(C). { A.op = TR_OP_SUB; A.value.wstr = NULL; A.leaf[0] = copyNode(B); A.leaf[1] = copyNode(C); A.valid = B.valid && C.valid; A.srcPos = pEval->GetSourcePos(); }
-expr(A) ::= expr(B) G_MULT expr(C). { A.op = TR_OP_MUL; A.value.wstr = NULL; A.leaf[0] = copyNode(B); A.leaf[1] = copyNode(C); A.valid = B.valid && C.valid; A.srcPos = pEval->GetSourcePos(); }
-expr(A) ::= expr(B) G_DIVIDE expr(C). { A.op = TR_OP_DIV; A.value.wstr = NULL; A.leaf[0] = copyNode(B); A.leaf[1] = copyNode(C); A.valid = B.valid && C.valid; A.srcPos = pEval->GetSourcePos(); }
-expr(A) ::= expr(B) G_EQUAL expr(C). { A.op = TR_OP_EQUAL; A.value.wstr = NULL; A.leaf[0] = copyNode(B); A.leaf[1] = copyNode(C); A.valid = B.valid && C.valid; A.srcPos = pEval->GetSourcePos(); }
+nt(A) ::= G_VALUE(B).
+{
+ A = newNode( pEval, TR_NUMBER, B.value );
+}
-expr(A) ::= expr(B) G_STRUCT_REF expr(C). { A.op = TR_STRUCT_REF; A.value.wstr = NULL; A.leaf[0] = copyNode(B); A.leaf[1] = copyNode(C); A.valid=B.valid && C.valid; A.srcPos = pEval->GetSourcePos(); }
+nt(A) ::= G_VALUE(B) G_UNIT(C).
+{
+ A = newNode( pEval, TR_NUMBER, B.value );
+ A->leaf[0] = newNode( pEval, TR_UNIT, C.value );
+}
-expr(A) ::= G_PARENL expr(B) G_PARENR. { A.op = B.op; A.value = B.value; A.valid=B.valid; A.leaf[0] = B.leaf[0]; A.leaf[1] = B.leaf[1]; A.srcPos = pEval->GetSourcePos(); }
-expr(A) ::= G_IDENTIFIER(F) G_PARENL expr(B) G_PARENR. { A.op = TR_OP_FUNC_CALL; A.value.wstr = NULL; A.leaf[0] = copyNode(F); A.leaf[1] = copyNode(B); A.valid = true; A.srcPos = pEval->GetSourcePos(); }
+nt(A) ::= G_STRING(B).
+{
+ A = newNode( pEval, TR_STRING, B.value );
+}
+
+nt(A) ::= G_IDENTIFIER(B).
+{
+ A = newNode( pEval, TR_IDENTIFIER, B.value );
+}
+
+nt(A) ::= nt(B) G_LESS_THAN nt(C).
+{
+ A = newNode( pEval, TR_OP_LESS );
+ A->leaf[0] = B;
+ A->leaf[1] = C;
+}
+
+nt(A) ::= nt(B) G_GREATER_THAN nt(C).
+{
+ A = newNode( pEval, TR_OP_GREATER );
+ A->leaf[0] = B;
+ A->leaf[1] = C;
+}
+
+nt(A) ::= nt(B) G_LESS_EQUAL_THAN nt(C).
+{
+ A = newNode( pEval, TR_OP_LESS_EQUAL );
+ A->leaf[0] = B;
+ A->leaf[1] = C;
+}
+
+nt(A) ::= nt(B) G_GREATER_EQUAL_THAN nt(C).
+{
+ A = newNode( pEval, TR_OP_GREATER_EQUAL );
+ A->leaf[0] = B;
+ A->leaf[1] = C;
+}
+
+nt(A) ::= nt(B) G_NOT_EQUAL nt(C).
+{
+ A = newNode( pEval, TR_OP_NOT_EQUAL );
+ A->leaf[0] = B;
+ A->leaf[1] = C;
+}
+
+
+nt(A) ::= nt(B) G_BOOL_AND nt(C).
+{
+ A = newNode( pEval, TR_OP_BOOL_AND );
+ A->leaf[0] = B;
+ A->leaf[1] = C;
+}
+
+nt(A) ::= nt(B) G_BOOL_OR nt(C).
+{
+ A = newNode( pEval, TR_OP_BOOL_OR );
+ A->leaf[0] = B;
+ A->leaf[1] = C;
+}
+
+nt(A) ::= nt(B) G_PLUS nt(C).
+{
+ A = newNode( pEval, TR_OP_ADD );
+ A->leaf[0] = B;
+ A->leaf[1] = C;
+}
+
+nt(A) ::= nt(B) G_MINUS nt(C).
+{
+ A = newNode( pEval, TR_OP_SUB );
+ A->leaf[0] = B;
+ A->leaf[1] = C;
+}
+
+nt(A) ::= nt(B) G_MULT nt(C).
+{
+ A = newNode( pEval, TR_OP_MUL );
+ A->leaf[0] = B;
+ A->leaf[1] = C;
+}
+
+nt(A) ::= nt(B) G_DIVIDE nt(C).
+{
+ A = newNode( pEval, TR_OP_DIV );
+ A->leaf[0] = B;
+ A->leaf[1] = C;
+}
+
+nt(A) ::= nt(B) G_EQUAL nt(C).
+{
+ A = newNode( pEval, TR_OP_EQUAL );
+ A->leaf[0] = B;
+ A->leaf[1] = C;
+}
+
+nt(A) ::= nt(B) G_STRUCT_REF nt(C).
+{
+ A = newNode( pEval, TR_STRUCT_REF );
+ A->leaf[0] = B;
+ A->leaf[1] = C;
+}
+
+nt(A) ::= G_PARENL nt(B) G_PARENR.
+{
+ A = newNode( pEval, B->op );
+ A->leaf[0] = B->leaf[0];
+ A->leaf[1] = B->leaf[1];
+}
+
+nt(A) ::= G_IDENTIFIER(F) G_PARENL nt(B) G_PARENR.
+{
+ A = newNode( pEval, TR_OP_FUNC_CALL );
+ A->leaf[0] = newNode( pEval, TR_IDENTIFIER, F.value);
+ A->leaf[1] = B;
+}
diff --git a/common/libeval_compiler/libeval_compiler.cpp b/common/libeval_compiler/libeval_compiler.cpp
index dbd69e2bc9..969817d1c3 100644
--- a/common/libeval_compiler/libeval_compiler.cpp
+++ b/common/libeval_compiler/libeval_compiler.cpp
@@ -50,44 +50,29 @@ namespace LIBEVAL
#define libeval_dbg(level, fmt, ...) \
- wxLogTrace( "libeval_compiler", fmt, __VA_ARGS__ )
+ wxLogTrace( "libeval_compiler", fmt, __VA_ARGS__ );
-TREE_NODE* copyNode( TREE_NODE& t )
+
+TREE_NODE* newNode( LIBEVAL::COMPILER* compiler, int op, const T_TOKEN_VALUE& value )
{
auto t2 = new TREE_NODE();
- t2->valid = t.valid;
-
- if( t.value.wstr )
- {
- t2->value.wstr = new wxString(*t.value.wstr);
- }
- else
- {
- t2->value.wstr = nullptr;
- }
- t2->value.type = t.value.type;
- t2->op = t.op;
- t2->leaf[0] = t.leaf[0];
- t2->leaf[1] = t.leaf[1];
- t2->isTerminal = false;
- t2->srcPos = t.srcPos;
- t2->uop = nullptr;
- return t2;
-}
-
-TREE_NODE* newNode( int op, int type, const wxString& value )
-{
- auto t2 = new TREE_NODE();
t2->valid = true;
- t2->value.wstr = new wxString( value );
+ t2->value.str = value.str ? new wxString( *value.str ) : nullptr;
+ t2->value.num = value.num;
+ t2->value.idx = value.idx;
t2->op = op;
- t2->value.type = type;
t2->leaf[0] = nullptr;
t2->leaf[1] = nullptr;
t2->isTerminal = false;
- t2->srcPos = -1;
+ t2->srcPos = compiler->GetSourcePos();
t2->uop = nullptr;
+
+ if(t2->value.str)
+ compiler->GcItem( t2->value.str );
+
+ compiler->GcItem( t2 );
+
return t2;
}
@@ -125,19 +110,17 @@ wxString UOP::Format() const
switch( m_op )
{
case TR_UOP_PUSH_VAR:
- str = wxString::Format( "PUSH VAR [%p]", m_arg );
+ str = wxString::Format( "PUSH VAR [%p]", m_ref.get() );
break;
case TR_UOP_PUSH_VALUE:
{
- VALUE* val = reinterpret_cast( m_arg );
-
- if( !val )
+ if( !m_value )
str = wxString::Format( "PUSH nullptr" );
- else if( val->GetType() == VT_NUMERIC )
- str = wxString::Format( "PUSH NUM [%.10f]", val->AsDouble() );
+ else if( m_value->GetType() == VT_NUMERIC )
+ str = wxString::Format( "PUSH NUM [%.10f]", m_value->AsDouble() );
else
- str = wxString::Format( "PUSH STR [%ls]", GetChars( val->AsString() ) );
+ str = wxString::Format( "PUSH STR [%ls]", GetChars( m_value->AsString() ) );
}
break;
@@ -161,7 +144,10 @@ wxString UOP::Format() const
UCODE::~UCODE()
{
for ( auto op : m_ucode )
+ {
+ printf("destroy uop %p\n", op );
delete op;
+ }
}
@@ -243,6 +229,15 @@ void COMPILER::Clear()
}
m_tree = nullptr;
+
+ for( auto tok : m_gcItems )
+ delete tok;
+
+ for( auto tok: m_gcStrings )
+ delete tok;
+
+ m_gcItems.clear();
+ m_gcStrings.clear();
}
@@ -273,6 +268,8 @@ bool COMPILER::Compile( const wxString& aString, UCODE* aCode, CONTEXT* aPreflig
m_parseFinished = false;
T_TOKEN tok;
+ tok.value.str = nullptr;
+
libeval_dbg(0, "str: '%s' empty: %d\n", aString.c_str(), !!aString.empty() );
if( aString.empty() )
@@ -286,8 +283,12 @@ bool COMPILER::Compile( const wxString& aString, UCODE* aCode, CONTEXT* aPreflig
m_sourcePos = m_tokenizer.GetPos();
tok = getToken();
+
+ if( tok.value.str )
+ GcItem( tok.value.str );
+
libeval_dbg(10, "parse: tok %d\n", tok.token );
- Parse( m_parser, tok.token, tok.value, this );
+ Parse( m_parser, tok.token, tok, this );
if ( m_errorStatus.pendingError )
return false;
@@ -295,7 +296,7 @@ bool COMPILER::Compile( const wxString& aString, UCODE* aCode, CONTEXT* aPreflig
if( m_parseFinished || tok.token == G_ENDS )
{
// Reset parser by passing zero as token ID, value is ignored.
- Parse( m_parser, 0, tok.value, this );
+ Parse( m_parser, 0, tok, this );
break;
}
} while( tok.token );
@@ -313,9 +314,11 @@ void COMPILER::newString( const wxString& aString )
m_parseFinished = false;
}
-COMPILER::T_TOKEN COMPILER::getToken()
+T_TOKEN COMPILER::getToken()
{
T_TOKEN rv;
+ rv.value.str = nullptr;
+
bool done = false;
do
@@ -336,13 +339,13 @@ COMPILER::T_TOKEN COMPILER::getToken()
}
-bool COMPILER::lexString( COMPILER::T_TOKEN& aToken )
+bool COMPILER::lexString( T_TOKEN& aToken )
{
wxString str = m_tokenizer.GetChars( []( int c ) -> bool { return c != '\''; } );
//printf("STR LIT '%s'\n", (const char *)str.c_str() );
aToken.token = G_STRING;
- aToken.value.value.wstr = new wxString( str );
+ aToken.value.str = new wxString( str );
m_tokenizer.NextChar( str.length() + 1 );
m_lexerState = LS_DEFAULT;
@@ -370,13 +373,14 @@ int COMPILER::resolveUnits()
}
-bool COMPILER::lexDefault( COMPILER::T_TOKEN& aToken )
+bool COMPILER::lexDefault( T_TOKEN& aToken )
{
T_TOKEN retval;
wxString current;
int convertFrom;
wxString msg;
+ retval.value.str = nullptr;
retval.token = G_ENDS;
//printf( "tokdone %d\n", !!m_tokenizer.Done() );
@@ -448,7 +452,7 @@ bool COMPILER::lexDefault( COMPILER::T_TOKEN& aToken )
// VALUE
extractNumber();
retval.token = G_VALUE;
- retval.value.value.wstr = new wxString( current );
+ retval.value.str = new wxString( current );
}
else if( ( convertFrom = resolveUnits() ) >= 0 )
{
@@ -460,7 +464,7 @@ bool COMPILER::lexDefault( COMPILER::T_TOKEN& aToken )
// The factor is assigned to the terminal UNIT. The actual
// conversion is done within a parser action.
retval.token = G_UNIT;
- retval.value.value.type = convertFrom;
+ retval.value.idx = convertFrom;
}
else if( ch == '\'' ) // string literal
{
@@ -477,7 +481,7 @@ bool COMPILER::lexDefault( COMPILER::T_TOKEN& aToken )
//printf("id '%s'\n", (const char *) current.c_str() );
//fflush( stdout );
retval.token = G_IDENTIFIER;
- retval.value.value.wstr = new wxString( current );
+ retval.value.str = new wxString( current );
m_tokenizer.NextChar( current.length() );
}
else if( m_tokenizer.MatchAhead( "==", []( int c ) -> bool { return c != '='; } ) )
@@ -540,9 +544,9 @@ bool COMPILER::lexDefault( COMPILER::T_TOKEN& aToken )
}
-const wxString formatNode( TREE_NODE* tok )
+const wxString formatNode( TREE_NODE* node )
{
- return *(tok->value.wstr);
+ return *(node->value.str);
}
@@ -592,13 +596,13 @@ void dumpNode( wxString& buf, TREE_NODE* tok, int depth = 0 )
case TR_OP_FUNC_CALL:
buf += "CALL '";
- buf += *tok->leaf[0]->value.wstr;
+ buf += *tok->leaf[0]->value.str;
buf += "': ";
dumpNode( buf, tok->leaf[1], depth + 1 );
break;
case TR_UNIT:
- str.Printf( "UNIT: %d ", tok->value.type );
+ str.Printf( "UNIT: %d ", tok->value.idx );
buf += str;
break;
}
@@ -644,21 +648,67 @@ void COMPILER::reportError( COMPILATION_STAGE stage, const wxString& aErrorMsg,
}
-void COMPILER::setRoot( TREE_NODE root )
+void COMPILER::setRoot( TREE_NODE *root )
{
- m_tree = copyNode( root );
+ m_tree = root;
}
void COMPILER::freeTree( LIBEVAL::TREE_NODE *tree )
{
+ printf("->FreeTre %p\n", tree );
+
if ( tree->leaf[0] )
freeTree( tree->leaf[0] );
if ( tree->leaf[1] )
freeTree( tree->leaf[1] );
- delete tree;
+ if( tree->uop )
+ {
+ printf("Free uop %p\n", tree->uop );
+ delete tree->uop;
+ }
+
+/* if( tree->value.str )
+ delete tree->value.str;
+
+ delete tree;*/
}
+void TREE_NODE::SetUop( int aOp, double aValue )
+{
+ if( uop )
+ delete uop;
+
+ std::unique_ptr val( new VALUE( aValue ) );
+ uop = new UOP( aOp, std::move( val ) );
+}
+
+void TREE_NODE::SetUop( int aOp, const wxString& aValue )
+{
+ if( uop )
+ delete uop;
+
+ std::unique_ptr val( new VALUE( aValue ) );
+ uop = new UOP( aOp, std::move( val ) );
+}
+
+void TREE_NODE::SetUop( int aOp, std::unique_ptr aRef )
+{
+ if( uop )
+ delete uop;
+
+ uop = new UOP( aOp, std::move( aRef ) );
+}
+
+void TREE_NODE::SetUop( int aOp, FUNC_CALL_REF aFunc, std::unique_ptr aRef )
+{
+ if( uop )
+ delete uop;
+
+ uop = new UOP( aOp, std::move( aFunc ), std::move( aRef ) );
+}
+
+
bool COMPILER::generateUCode( UCODE* aCode, CONTEXT* aPreflightContext )
{
std::vector stack;
@@ -706,9 +756,9 @@ bool COMPILER::generateUCode( UCODE* aCode, CONTEXT* aPreflightContext )
{
case TR_IDENTIFIER:
{
- wxString itemName = *node->leaf[0]->value.wstr;
- wxString propName = *node->leaf[1]->value.wstr;
- VAR_REF* vref = aCode->CreateVarRef( itemName, propName );
+ wxString itemName = *node->leaf[0]->value.str;
+ wxString propName = *node->leaf[1]->value.str;
+ std::unique_ptr vref = aCode->CreateVarRef( itemName, propName );
if( !vref )
{
@@ -724,14 +774,14 @@ bool COMPILER::generateUCode( UCODE* aCode, CONTEXT* aPreflightContext )
return false;
}
- node->uop = makeUop( TR_UOP_PUSH_VAR, vref );
+ node->SetUop( TR_UOP_PUSH_VAR, std::move( vref ) );
node->isTerminal = true;
break;
}
case TR_OP_FUNC_CALL:
{
- wxString itemName = *node->leaf[0]->value.wstr;
- VAR_REF* vref = aCode->CreateVarRef( itemName, "" );
+ wxString itemName = *node->leaf[0]->value.str;
+ std::unique_ptr vref = aCode->CreateVarRef( itemName, "" );
if( !vref )
{
@@ -740,7 +790,7 @@ bool COMPILER::generateUCode( UCODE* aCode, CONTEXT* aPreflightContext )
return false;
}
- wxString functionName = *node->leaf[1]->leaf[0]->value.wstr;
+ wxString functionName = *node->leaf[1]->leaf[0]->value.str;
auto func = aCode->CreateFuncCall( functionName );
libeval_dbg(10, "emit func call: %s\n", (const char*) functionName.c_str() );
@@ -775,8 +825,8 @@ bool COMPILER::generateUCode( UCODE* aCode, CONTEXT* aPreflightContext )
#endif
/* SREF -> FUNC_CALL -> leaf0/1 */
- node->leaf[1]->leaf[0]->leaf[0] = nullptr;
- node->leaf[1]->leaf[0]->leaf[1] = nullptr;
+ // node->leaf[1]->leaf[0]->leaf[0] = nullptr;
+ // node->leaf[1]->leaf[0]->leaf[1] = nullptr;
#if 0
if( aPreflightContext->IsErrorPending() )
@@ -791,7 +841,7 @@ bool COMPILER::generateUCode( UCODE* aCode, CONTEXT* aPreflightContext )
visitedNodes.insert( node->leaf[0] );
visitedNodes.insert( node->leaf[1]->leaf[0] );
- node->uop = makeUop( TR_OP_METHOD_CALL, func, vref );
+ node->SetUop( TR_OP_METHOD_CALL, func, std::move( vref ) );
node->isTerminal = false;
}
break;
@@ -807,16 +857,16 @@ bool COMPILER::generateUCode( UCODE* aCode, CONTEXT* aPreflightContext )
if( son && son->op == TR_UNIT )
{
//printf( "HandleUnit: %s unit %d\n", node->value.str, son->value.type );
- int units = son->value.type;
- value = m_unitResolver->Convert( *node->value.wstr, units );
+ int units = son->value.idx;
+ value = m_unitResolver->Convert( *node->value.str, units );
visitedNodes.insert( son );
}
else
{
- value = wxAtof( *node->value.wstr );
+ value = wxAtof( *node->value.str );
}
- node->uop = makeUop( TR_UOP_PUSH_VALUE, value );
+ node->SetUop( TR_UOP_PUSH_VALUE, value );
node->isTerminal = true;
break;
@@ -824,28 +874,28 @@ bool COMPILER::generateUCode( UCODE* aCode, CONTEXT* aPreflightContext )
case TR_STRING:
{
- node->uop = makeUop( TR_UOP_PUSH_VALUE, *node->value.wstr );
+ node->SetUop( TR_UOP_PUSH_VALUE, *node->value.str );
node->isTerminal = true;
break;
}
case TR_IDENTIFIER:
{
- VAR_REF* vref = aCode->CreateVarRef( *node->value.wstr, "" );
+ std::unique_ptr vref = aCode->CreateVarRef( *node->value.str, "" );
if( !vref )
{
- msg.Printf( _( "Unrecognized item '%s'" ), *node->value.wstr );
- reportError( CST_CODEGEN, msg, node->srcPos - (int) strlen( *node->value.wstr ) );
+ msg.Printf( _( "Unrecognized item '%s'" ), *node->value.str );
+ reportError( CST_CODEGEN, msg, node->srcPos - (int) strlen( *node->value.str ) );
return false;
}
- node->uop = makeUop( TR_UOP_PUSH_VALUE, vref );
+ node->SetUop( TR_UOP_PUSH_VALUE, std::move( vref ) );
break;
}
default:
- node->uop = makeUop( node->op );
+ node->SetUop( node->op );
break;
}
@@ -865,7 +915,10 @@ bool COMPILER::generateUCode( UCODE* aCode, CONTEXT* aPreflightContext )
visitedNodes.insert( node );
if( node->uop )
+ {
aCode->AddOp( node->uop );
+ node->uop = nullptr;
+ }
stack.pop_back();
}
@@ -883,18 +936,18 @@ void UOP::Exec( CONTEXT* ctx )
case TR_UOP_PUSH_VAR:
{
auto value = ctx->AllocValue();
- value->Set( reinterpret_cast( m_arg )->GetValue( ctx ) );
+ value->Set( m_ref->GetValue( ctx ) );
ctx->Push( value );
}
break;
case TR_UOP_PUSH_VALUE:
- ctx->Push( reinterpret_cast( m_arg ) );
+ ctx->Push( m_value.get() );
return;
case TR_OP_METHOD_CALL:
//printf("CALL METHOD %s\n" );
- m_func( ctx, m_arg );
+ m_func( ctx, m_ref.get() );
return;
default:
diff --git a/common/marker_base.cpp b/common/marker_base.cpp
index 93e99a406a..165a0e04a5 100644
--- a/common/marker_base.cpp
+++ b/common/marker_base.cpp
@@ -85,6 +85,7 @@ MARKER_BASE::MARKER_BASE( int aScalingFactor, RC_ITEM* aItem, TYPEMARKER aType )
MARKER_BASE::~MARKER_BASE()
{
+ printf("del rcitem %p\n", m_rcItem );
delete m_rcItem;
}
diff --git a/include/libeval_compiler/libeval_compiler.h b/include/libeval_compiler/libeval_compiler.h
index a33fdf856d..a16653144c 100644
--- a/include/libeval_compiler/libeval_compiler.h
+++ b/include/libeval_compiler/libeval_compiler.h
@@ -92,18 +92,32 @@ enum TOKEN_TYPE_T
TR_UNIT = 6
};
-#define LIBEVAL_MAX_LITERAL_LENGTH 1024
-
class UOP;
+class UCODE;
+class CONTEXT;
+class VAR_REF;
-struct TREE_NODE
+typedef std::function FUNC_CALL_REF;
+
+struct T_TOKEN_VALUE
{
- struct value_s
- {
- wxString *wstr;
- //char str[LIBEVAL_MAX_LITERAL_LENGTH];
- int type;
- } value;
+ wxString *str;
+ double num;
+ int idx;
+};
+
+constexpr T_TOKEN_VALUE defaultTokenValue = { nullptr, 0.0, 0 };
+
+struct T_TOKEN
+{
+ int token;
+ T_TOKEN_VALUE value;
+};
+
+class TREE_NODE
+{
+public:
+ T_TOKEN_VALUE value;
int op;
TREE_NODE* leaf[2];
@@ -111,10 +125,15 @@ struct TREE_NODE
bool valid;
bool isTerminal;
int srcPos;
+
+ void SetUop( int aOp, double aValue );
+ void SetUop( int aOp, const wxString& aValue );
+ void SetUop( int aOp, std::unique_ptr aRef = nullptr );
+ void SetUop( int aOp, FUNC_CALL_REF aFunc, std::unique_ptr aRef = nullptr );
};
-TREE_NODE* copyNode( TREE_NODE& t );
-TREE_NODE* newNode( int op, int type, const wxString& value );
+
+TREE_NODE* newNode( LIBEVAL::COMPILER* compiler, int op, const T_TOKEN_VALUE& value = defaultTokenValue);
class UNIT_RESOLVER
{
@@ -141,7 +160,7 @@ public:
};
-class VALUE
+class VALUE
{
public:
VALUE():
@@ -214,14 +233,12 @@ private:
wxString m_valueStr;
};
-
-class UCODE;
-class CONTEXT;
-
-
class VAR_REF
{
public:
+ VAR_REF() {};
+ virtual ~VAR_REF() {};
+
virtual VAR_TYPE_T GetType() = 0;
virtual VALUE GetValue( CONTEXT* aCtx ) = 0;
};
@@ -278,8 +295,6 @@ class UCODE
public:
virtual ~UCODE();
- typedef std::function FUNC_PTR;
-
void AddOp( UOP* uop )
{
m_ucode.push_back(uop);
@@ -288,17 +303,18 @@ public:
VALUE* Run( CONTEXT* ctx );
wxString Dump() const;
- virtual VAR_REF* CreateVarRef( const wxString& var, const wxString& field )
+ virtual std::unique_ptr CreateVarRef( const wxString& var, const wxString& field )
{
return nullptr;
};
- virtual FUNC_PTR CreateFuncCall( const wxString& name )
+ virtual FUNC_CALL_REF CreateFuncCall( const wxString& name )
{
return nullptr;
};
-private:
+protected:
+
std::vector m_ucode;
};
@@ -306,25 +322,39 @@ private:
class UOP
{
public:
- UOP( int op, void* arg ) :
+ UOP( int op, std::unique_ptr value ) :
m_op( op ),
- m_arg( arg )
+ m_ref(nullptr),
+ m_value( std::move( value ) )
{};
- UOP( int op, UCODE::FUNC_PTR func, void *arg ) :
+ UOP( int op, std::unique_ptr vref ) :
m_op( op ),
- m_arg(arg),
- m_func( std::move( func ) )
+ m_ref( std::move( vref ) ),
+ m_value(nullptr)
{};
+ UOP( int op, FUNC_CALL_REF func, std::unique_ptr vref = nullptr ) :
+ m_op( op ),
+ m_func( std::move( func ) ),
+ m_ref( std::move( vref ) ),
+ m_value(nullptr)
+ {};
+
+ ~UOP()
+ {
+ }
+
void Exec( CONTEXT* ctx );
wxString Format() const;
private:
int m_op;
- void* m_arg;
- UCODE::FUNC_PTR m_func;
+
+ FUNC_CALL_REF m_func;
+ std::unique_ptr m_ref;
+ std::unique_ptr m_value;
};
class TOKENIZER
@@ -393,7 +423,7 @@ public:
int GetSourcePos() const { return m_sourcePos; }
- void setRoot( LIBEVAL::TREE_NODE root );
+ void setRoot( LIBEVAL::TREE_NODE *root );
void freeTree( LIBEVAL::TREE_NODE *tree );
bool Compile( const wxString& aString, UCODE* aCode, CONTEXT* aPreflightContext );
@@ -402,6 +432,9 @@ public:
bool IsErrorPending() const { return m_errorStatus.pendingError; }
const ERROR_STATUS& GetError() const { return m_errorStatus; }
+ void GcItem( TREE_NODE* aItem ) { m_gcItems.push_back( aItem ); }
+ void GcItem( wxString* aItem ) { m_gcStrings.push_back( aItem ); }
+
protected:
enum LEXER_STATE
{
@@ -415,13 +448,6 @@ protected:
void reportError( COMPILATION_STAGE stage, const wxString& aErrorMsg, int aPos = -1 );
- /* Token type used by the tokenizer */
- struct T_TOKEN
- {
- int token;
- TREE_NODE value;
- };
-
/* Begin processing of a new input string */
void newString( const wxString& aString );
@@ -432,30 +458,6 @@ protected:
int resolveUnits();
- UOP* makeUop( int op, double value )
- {
- auto uop = new UOP( op, new VALUE( value ) );
- return uop;
- }
-
- UOP* makeUop( int op, const wxString& value )
- {
- UOP* uop = new UOP( op, new VALUE( value ) );
- return uop;
- }
-
- UOP* makeUop( int op, VAR_REF* aRef = nullptr )
- {
- UOP* uop = new UOP( op, aRef );
- return uop;
- }
-
- UOP* makeUop( int op, UCODE::FUNC_PTR aFunc, void *arg = nullptr )
- {
- UOP* uop = new UOP( op, std::move( aFunc ), arg );
- return uop;
- }
-
protected:
/* Token state for input string. */
void* m_parser; // the current lemon parser state machine
@@ -469,6 +471,8 @@ protected:
TREE_NODE* m_tree;
ERROR_STATUS m_errorStatus;
+ std::vector m_gcItems;
+ std::vector m_gcStrings;
std::function m_errorCallback;
};
diff --git a/thirdparty/lemon/lempar.c b/thirdparty/lemon/lempar.c
index c82e33298a..704ff501b6 100644
--- a/thirdparty/lemon/lempar.c
+++ b/thirdparty/lemon/lempar.c
@@ -25,13 +25,16 @@
#include
#include
/************ Begin %include sections from the grammar ************************/
-%%
+#line 37 "grammar.lemon"
+
+#include
+#include
+#line 33 "grammar.c"
/**************** End of %include directives **********************************/
/* These constants specify the various numeric values for terminal symbols
** in a format understandable to "makeheaders". This section is blank unless
** "lemon" is run with the "-m" command-line option.
***************** Begin makeheaders token definitions *************************/
-%%
/**************** End makeheaders token definitions ***************************/
/* The next sections is a series of control #defines.
@@ -89,7 +92,39 @@
# define INTERFACE 1
#endif
/************* Begin control #defines *****************************************/
-%%
+#define YYCODETYPE unsigned char
+#define YYNOCODE 29
+#define YYACTIONTYPE unsigned char
+#define ParseTOKENTYPE LIBEVAL::T_TOKEN
+typedef union {
+ int yyinit;
+ ParseTOKENTYPE yy0;
+ LIBEVAL::TREE_NODE* yy31;
+} YYMINORTYPE;
+#ifndef YYSTACKDEPTH
+#define YYSTACKDEPTH 100
+#endif
+#define ParseARG_SDECL LIBEVAL::COMPILER* pEval ;
+#define ParseARG_PDECL , LIBEVAL::COMPILER* pEval
+#define ParseARG_PARAM ,pEval
+#define ParseARG_FETCH LIBEVAL::COMPILER* pEval =yypParser->pEval ;
+#define ParseARG_STORE yypParser->pEval =pEval ;
+#define ParseCTX_SDECL
+#define ParseCTX_PDECL
+#define ParseCTX_PARAM
+#define ParseCTX_FETCH
+#define ParseCTX_STORE
+#define YYNSTATE 35
+#define YYNRULE 24
+#define YYNTOKEN 25
+#define YY_MAX_SHIFT 34
+#define YY_MIN_SHIFTREDUCE 43
+#define YY_MAX_SHIFTREDUCE 66
+#define YY_ERROR_ACTION 67
+#define YY_ACCEPT_ACTION 68
+#define YY_NO_ACTION 69
+#define YY_MIN_REDUCE 70
+#define YY_MAX_REDUCE 93
/************* End control #defines *******************************************/
#define YY_NLOOKAHEAD ((int)(sizeof(yy_lookahead)/sizeof(yy_lookahead[0])))
@@ -156,7 +191,61 @@
** yy_default[] Default action for each state.
**
*********** Begin parsing tables **********************************************/
-%%
+#define YY_ACTTAB_COUNT (135)
+static const YYACTIONTYPE yy_action[] = {
+ /* 0 */ 19, 68, 1, 1, 10, 9, 17, 16, 14, 13,
+ /* 10 */ 12, 4, 11, 87, 8, 7, 5, 6, 3, 5,
+ /* 20 */ 6, 3, 10, 9, 61, 16, 14, 13, 12, 4,
+ /* 30 */ 11, 22, 8, 7, 5, 6, 3, 31, 32, 28,
+ /* 40 */ 10, 9, 62, 16, 14, 13, 12, 4, 11, 29,
+ /* 50 */ 8, 7, 5, 6, 3, 19, 43, 9, 92, 16,
+ /* 60 */ 14, 13, 12, 4, 11, 23, 8, 7, 5, 6,
+ /* 70 */ 3, 67, 67, 67, 67, 67, 67, 67, 8, 7,
+ /* 80 */ 5, 6, 3, 16, 14, 13, 12, 4, 11, 33,
+ /* 90 */ 8, 7, 5, 6, 3, 90, 33, 20, 24, 25,
+ /* 100 */ 26, 3, 27, 69, 18, 21, 45, 15, 66, 34,
+ /* 110 */ 46, 2, 33, 69, 69, 66, 34, 46, 2, 69,
+ /* 120 */ 69, 69, 69, 69, 69, 69, 69, 69, 69, 69,
+ /* 130 */ 69, 69, 34, 46, 2,
+};
+static const YYCODETYPE yy_lookahead[] = {
+ /* 0 */ 25, 26, 27, 28, 4, 5, 25, 7, 8, 9,
+ /* 10 */ 10, 11, 12, 25, 14, 15, 16, 17, 18, 16,
+ /* 20 */ 17, 18, 4, 5, 24, 7, 8, 9, 10, 11,
+ /* 30 */ 12, 25, 14, 15, 16, 17, 18, 25, 25, 25,
+ /* 40 */ 4, 5, 24, 7, 8, 9, 10, 11, 12, 25,
+ /* 50 */ 14, 15, 16, 17, 18, 25, 20, 5, 28, 7,
+ /* 60 */ 8, 9, 10, 11, 12, 25, 14, 15, 16, 17,
+ /* 70 */ 18, 7, 8, 9, 10, 11, 12, 18, 14, 15,
+ /* 80 */ 16, 17, 18, 7, 8, 9, 10, 11, 12, 1,
+ /* 90 */ 14, 15, 16, 17, 18, 0, 1, 25, 25, 25,
+ /* 100 */ 25, 18, 25, 29, 25, 25, 19, 23, 20, 21,
+ /* 110 */ 22, 23, 1, 29, 29, 20, 21, 22, 23, 29,
+ /* 120 */ 29, 29, 29, 29, 29, 29, 29, 29, 29, 29,
+ /* 130 */ 29, 29, 21, 22, 23, 29, 29, 29,
+};
+#define YY_SHIFT_COUNT (34)
+#define YY_SHIFT_MIN (0)
+#define YY_SHIFT_MAX (111)
+static const unsigned char yy_shift_ofst[] = {
+ /* 0 */ 88, 95, 111, 111, 111, 111, 111, 111, 111, 111,
+ /* 10 */ 111, 111, 111, 111, 111, 111, 111, 0, 18, 36,
+ /* 20 */ 52, 64, 64, 76, 64, 64, 64, 64, 3, 3,
+ /* 30 */ 59, 83, 83, 84, 87,
+};
+#define YY_REDUCE_COUNT (16)
+#define YY_REDUCE_MIN (-25)
+#define YY_REDUCE_MAX (80)
+static const signed char yy_reduce_ofst[] = {
+ /* 0 */ -25, 30, -19, -12, 6, 12, 13, 14, 24, 40,
+ /* 10 */ 72, 73, 74, 75, 77, 79, 80,
+};
+static const YYACTIONTYPE yy_default[] = {
+ /* 0 */ 67, 67, 67, 67, 67, 67, 67, 67, 67, 67,
+ /* 10 */ 67, 67, 67, 67, 67, 67, 67, 67, 67, 67,
+ /* 20 */ 80, 75, 86, 81, 79, 78, 77, 76, 83, 82,
+ /* 30 */ 87, 85, 84, 74, 71,
+};
/********** End of lemon-generated parsing tables *****************************/
/* The next table maps tokens (terminal symbols) into fallback tokens.
@@ -175,7 +264,6 @@
*/
#ifdef YYFALLBACK
static const YYCODETYPE yyFallback[] = {
-%%
};
#endif /* YYFALLBACK */
@@ -263,7 +351,35 @@ void ParseTrace(FILE *TraceFILE, char *zTracePrompt){
/* For tracing shifts, the names of all terminals and nonterminals
** are required. The following table supplies these names */
static const char *const yyTokenName[] = {
-%%
+ /* 0 */ "$",
+ /* 1 */ "G_IDENTIFIER",
+ /* 2 */ "G_ASSIGN",
+ /* 3 */ "G_SEMCOL",
+ /* 4 */ "G_BOOL_AND",
+ /* 5 */ "G_BOOL_OR",
+ /* 6 */ "G_BOOL_XOR",
+ /* 7 */ "G_LESS_THAN",
+ /* 8 */ "G_GREATER_THAN",
+ /* 9 */ "G_LESS_EQUAL_THAN",
+ /* 10 */ "G_GREATER_EQUAL_THAN",
+ /* 11 */ "G_EQUAL",
+ /* 12 */ "G_NOT_EQUAL",
+ /* 13 */ "G_BOOL_NOT",
+ /* 14 */ "G_PLUS",
+ /* 15 */ "G_MINUS",
+ /* 16 */ "G_DIVIDE",
+ /* 17 */ "G_MULT",
+ /* 18 */ "G_STRUCT_REF",
+ /* 19 */ "G_UNIT",
+ /* 20 */ "G_ENDS",
+ /* 21 */ "G_VALUE",
+ /* 22 */ "G_STRING",
+ /* 23 */ "G_PARENL",
+ /* 24 */ "G_PARENR",
+ /* 25 */ "nt",
+ /* 26 */ "main",
+ /* 27 */ "in",
+ /* 28 */ "stmt",
};
#endif /* defined(YYCOVERAGE) || !defined(NDEBUG) */
@@ -271,7 +387,30 @@ static const char *const yyTokenName[] = {
/* For tracing reduce actions, the names of all rules are required.
*/
static const char *const yyRuleName[] = {
-%%
+ /* 0 */ "stmt ::= nt G_ENDS",
+ /* 1 */ "nt ::= G_VALUE",
+ /* 2 */ "nt ::= G_VALUE G_UNIT",
+ /* 3 */ "nt ::= G_STRING",
+ /* 4 */ "nt ::= G_IDENTIFIER",
+ /* 5 */ "nt ::= nt G_LESS_THAN nt",
+ /* 6 */ "nt ::= nt G_GREATER_THAN nt",
+ /* 7 */ "nt ::= nt G_LESS_EQUAL_THAN nt",
+ /* 8 */ "nt ::= nt G_GREATER_EQUAL_THAN nt",
+ /* 9 */ "nt ::= nt G_NOT_EQUAL nt",
+ /* 10 */ "nt ::= nt G_BOOL_AND nt",
+ /* 11 */ "nt ::= nt G_BOOL_OR nt",
+ /* 12 */ "nt ::= nt G_PLUS nt",
+ /* 13 */ "nt ::= nt G_MINUS nt",
+ /* 14 */ "nt ::= nt G_MULT nt",
+ /* 15 */ "nt ::= nt G_DIVIDE nt",
+ /* 16 */ "nt ::= nt G_EQUAL nt",
+ /* 17 */ "nt ::= nt G_STRUCT_REF nt",
+ /* 18 */ "nt ::= G_PARENL nt G_PARENR",
+ /* 19 */ "nt ::= G_IDENTIFIER G_PARENL nt G_PARENR",
+ /* 20 */ "main ::= in",
+ /* 21 */ "in ::= stmt",
+ /* 22 */ "in ::= in stmt",
+ /* 23 */ "stmt ::= G_ENDS",
};
#endif /* NDEBUG */
@@ -397,7 +536,6 @@ static void yy_destructor(
** inside the C code.
*/
/********* Begin destructor definitions ***************************************/
-%%
/********* End destructor definitions *****************************************/
default: break; /* If no destructor action specified: do nothing */
}
@@ -521,18 +659,15 @@ static YYACTIONTYPE yy_find_shift_action(
do{
i = yy_shift_ofst[stateno];
assert( i>=0 );
- assert( i<=YY_ACTTAB_COUNT );
- assert( i+YYNTOKEN<=(int)YY_NLOOKAHEAD );
+ /* assert( i+YYNTOKEN<=(int)YY_NLOOKAHEAD ); */
assert( iLookAhead!=YYNOCODE );
assert( iLookAhead < YYNTOKEN );
i += iLookAhead;
- assert( i<(int)YY_NLOOKAHEAD );
- if( yy_lookahead[i]!=iLookAhead ){
+ if( i>=YY_NLOOKAHEAD || yy_lookahead[i]!=iLookAhead ){
#ifdef YYFALLBACK
YYCODETYPE iFallback; /* Fallback token */
- assert( iLookAhead %s\n",
@@ -547,8 +682,16 @@ static YYACTIONTYPE yy_find_shift_action(
#ifdef YYWILDCARD
{
int j = i - iLookAhead + YYWILDCARD;
- assert( j<(int)(sizeof(yy_lookahead)/sizeof(yy_lookahead[0])) );
- if( yy_lookahead[j]==YYWILDCARD && iLookAhead>0 ){
+ if(
+#if YY_SHIFT_MIN+YYWILDCARD<0
+ j>=0 &&
+#endif
+#if YY_SHIFT_MAX+YYWILDCARD>=YY_ACTTAB_COUNT
+ j0
+ ){
#ifndef NDEBUG
if( yyTraceFILE ){
fprintf(yyTraceFILE, "%sWILDCARD %s => %s\n",
@@ -562,7 +705,6 @@ static YYACTIONTYPE yy_find_shift_action(
#endif /* YYWILDCARD */
return yy_default[stateno];
}else{
- assert( i>=0 && isetRoot(yymsp[-1].minor.yy31); }
+#line 972 "grammar.c"
+ break;
+ case 1: /* nt ::= G_VALUE */
+#line 61 "grammar.lemon"
+{
+ yylhsminor.yy31 = newNode( pEval, TR_NUMBER, yymsp[0].minor.yy0.value );
+}
+#line 979 "grammar.c"
+ yymsp[0].minor.yy31 = yylhsminor.yy31;
+ break;
+ case 2: /* nt ::= G_VALUE G_UNIT */
+#line 66 "grammar.lemon"
+{
+ yylhsminor.yy31 = newNode( pEval, TR_NUMBER, yymsp[-1].minor.yy0.value );
+ yylhsminor.yy31->leaf[0] = newNode( pEval, TR_UNIT, yymsp[0].minor.yy0.value );
+}
+#line 988 "grammar.c"
+ yymsp[-1].minor.yy31 = yylhsminor.yy31;
+ break;
+ case 3: /* nt ::= G_STRING */
+#line 72 "grammar.lemon"
+{
+ yylhsminor.yy31 = newNode( pEval, TR_STRING, yymsp[0].minor.yy0.value );
+}
+#line 996 "grammar.c"
+ yymsp[0].minor.yy31 = yylhsminor.yy31;
+ break;
+ case 4: /* nt ::= G_IDENTIFIER */
+#line 77 "grammar.lemon"
+{
+ yylhsminor.yy31 = newNode( pEval, TR_IDENTIFIER, yymsp[0].minor.yy0.value );
+}
+#line 1004 "grammar.c"
+ yymsp[0].minor.yy31 = yylhsminor.yy31;
+ break;
+ case 5: /* nt ::= nt G_LESS_THAN nt */
+#line 82 "grammar.lemon"
+{
+ yylhsminor.yy31 = newNode( pEval, TR_OP_LESS );
+ yylhsminor.yy31->leaf[0] = yymsp[-2].minor.yy31;
+ yylhsminor.yy31->leaf[1] = yymsp[0].minor.yy31;
+}
+#line 1014 "grammar.c"
+ yymsp[-2].minor.yy31 = yylhsminor.yy31;
+ break;
+ case 6: /* nt ::= nt G_GREATER_THAN nt */
+#line 89 "grammar.lemon"
+{
+ yylhsminor.yy31 = newNode( pEval, TR_OP_GREATER );
+ yylhsminor.yy31->leaf[0] = yymsp[-2].minor.yy31;
+ yylhsminor.yy31->leaf[1] = yymsp[0].minor.yy31;
+}
+#line 1024 "grammar.c"
+ yymsp[-2].minor.yy31 = yylhsminor.yy31;
+ break;
+ case 7: /* nt ::= nt G_LESS_EQUAL_THAN nt */
+#line 96 "grammar.lemon"
+{
+ yylhsminor.yy31 = newNode( pEval, TR_OP_LESS_EQUAL );
+ yylhsminor.yy31->leaf[0] = yymsp[-2].minor.yy31;
+ yylhsminor.yy31->leaf[1] = yymsp[0].minor.yy31;
+}
+#line 1034 "grammar.c"
+ yymsp[-2].minor.yy31 = yylhsminor.yy31;
+ break;
+ case 8: /* nt ::= nt G_GREATER_EQUAL_THAN nt */
+#line 103 "grammar.lemon"
+{
+ yylhsminor.yy31 = newNode( pEval, TR_OP_GREATER_EQUAL );
+ yylhsminor.yy31->leaf[0] = yymsp[-2].minor.yy31;
+ yylhsminor.yy31->leaf[1] = yymsp[0].minor.yy31;
+}
+#line 1044 "grammar.c"
+ yymsp[-2].minor.yy31 = yylhsminor.yy31;
+ break;
+ case 9: /* nt ::= nt G_NOT_EQUAL nt */
+#line 110 "grammar.lemon"
+{
+ yylhsminor.yy31 = newNode( pEval, TR_OP_NOT_EQUAL );
+ yylhsminor.yy31->leaf[0] = yymsp[-2].minor.yy31;
+ yylhsminor.yy31->leaf[1] = yymsp[0].minor.yy31;
+}
+#line 1054 "grammar.c"
+ yymsp[-2].minor.yy31 = yylhsminor.yy31;
+ break;
+ case 10: /* nt ::= nt G_BOOL_AND nt */
+#line 118 "grammar.lemon"
+{
+ yylhsminor.yy31 = newNode( pEval, TR_OP_BOOL_AND );
+ yylhsminor.yy31->leaf[0] = yymsp[-2].minor.yy31;
+ yylhsminor.yy31->leaf[1] = yymsp[0].minor.yy31;
+}
+#line 1064 "grammar.c"
+ yymsp[-2].minor.yy31 = yylhsminor.yy31;
+ break;
+ case 11: /* nt ::= nt G_BOOL_OR nt */
+#line 125 "grammar.lemon"
+{
+ yylhsminor.yy31 = newNode( pEval, TR_OP_BOOL_OR );
+ yylhsminor.yy31->leaf[0] = yymsp[-2].minor.yy31;
+ yylhsminor.yy31->leaf[1] = yymsp[0].minor.yy31;
+}
+#line 1074 "grammar.c"
+ yymsp[-2].minor.yy31 = yylhsminor.yy31;
+ break;
+ case 12: /* nt ::= nt G_PLUS nt */
+#line 132 "grammar.lemon"
+{
+ yylhsminor.yy31 = newNode( pEval, TR_OP_ADD );
+ yylhsminor.yy31->leaf[0] = yymsp[-2].minor.yy31;
+ yylhsminor.yy31->leaf[1] = yymsp[0].minor.yy31;
+}
+#line 1084 "grammar.c"
+ yymsp[-2].minor.yy31 = yylhsminor.yy31;
+ break;
+ case 13: /* nt ::= nt G_MINUS nt */
+#line 139 "grammar.lemon"
+{
+ yylhsminor.yy31 = newNode( pEval, TR_OP_SUB );
+ yylhsminor.yy31->leaf[0] = yymsp[-2].minor.yy31;
+ yylhsminor.yy31->leaf[1] = yymsp[0].minor.yy31;
+}
+#line 1094 "grammar.c"
+ yymsp[-2].minor.yy31 = yylhsminor.yy31;
+ break;
+ case 14: /* nt ::= nt G_MULT nt */
+#line 146 "grammar.lemon"
+{
+ yylhsminor.yy31 = newNode( pEval, TR_OP_MUL );
+ yylhsminor.yy31->leaf[0] = yymsp[-2].minor.yy31;
+ yylhsminor.yy31->leaf[1] = yymsp[0].minor.yy31;
+}
+#line 1104 "grammar.c"
+ yymsp[-2].minor.yy31 = yylhsminor.yy31;
+ break;
+ case 15: /* nt ::= nt G_DIVIDE nt */
+#line 153 "grammar.lemon"
+{
+ yylhsminor.yy31 = newNode( pEval, TR_OP_DIV );
+ yylhsminor.yy31->leaf[0] = yymsp[-2].minor.yy31;
+ yylhsminor.yy31->leaf[1] = yymsp[0].minor.yy31;
+}
+#line 1114 "grammar.c"
+ yymsp[-2].minor.yy31 = yylhsminor.yy31;
+ break;
+ case 16: /* nt ::= nt G_EQUAL nt */
+#line 160 "grammar.lemon"
+{
+ yylhsminor.yy31 = newNode( pEval, TR_OP_EQUAL );
+ yylhsminor.yy31->leaf[0] = yymsp[-2].minor.yy31;
+ yylhsminor.yy31->leaf[1] = yymsp[0].minor.yy31;
+}
+#line 1124 "grammar.c"
+ yymsp[-2].minor.yy31 = yylhsminor.yy31;
+ break;
+ case 17: /* nt ::= nt G_STRUCT_REF nt */
+#line 167 "grammar.lemon"
+{
+ yylhsminor.yy31 = newNode( pEval, TR_STRUCT_REF );
+ yylhsminor.yy31->leaf[0] = yymsp[-2].minor.yy31;
+ yylhsminor.yy31->leaf[1] = yymsp[0].minor.yy31;
+}
+#line 1134 "grammar.c"
+ yymsp[-2].minor.yy31 = yylhsminor.yy31;
+ break;
+ case 18: /* nt ::= G_PARENL nt G_PARENR */
+#line 174 "grammar.lemon"
+{
+ yymsp[-2].minor.yy31 = newNode( pEval, yymsp[-1].minor.yy31->op );
+ yymsp[-2].minor.yy31->leaf[0] = yymsp[-1].minor.yy31->leaf[0];
+ yymsp[-2].minor.yy31->leaf[1] = yymsp[-1].minor.yy31->leaf[1];
+}
+#line 1144 "grammar.c"
+ break;
+ case 19: /* nt ::= G_IDENTIFIER G_PARENL nt G_PARENR */
+#line 181 "grammar.lemon"
+{
+ yylhsminor.yy31 = newNode( pEval, TR_OP_FUNC_CALL );
+ yylhsminor.yy31->leaf[0] = newNode( pEval, TR_IDENTIFIER, yymsp[-3].minor.yy0.value);
+ yylhsminor.yy31->leaf[1] = yymsp[-1].minor.yy31;
+}
+#line 1153 "grammar.c"
+ yymsp[-3].minor.yy31 = yylhsminor.yy31;
+ break;
+ default:
+ /* (20) main ::= in */ yytestcase(yyruleno==20);
+ /* (21) in ::= stmt (OPTIMIZED OUT) */ assert(yyruleno!=21);
+ /* (22) in ::= in stmt */ yytestcase(yyruleno==22);
+ /* (23) stmt ::= G_ENDS */ yytestcase(yyruleno==23);
+ break;
/********** End reduce actions ************************************************/
};
assert( yyrulenoparseError("Syntax error");
+#line 1223 "grammar.c"
/************ End %syntax_error code ******************************************/
ParseARG_STORE /* Suppress warning about unused %extra_argument variable */
ParseCTX_STORE
@@ -866,7 +1245,10 @@ static void yy_accept(
/* Here code is inserted which will be executed whenever the
** parser accepts */
/*********** Begin %parse_accept code *****************************************/
-%%
+#line 46 "grammar.lemon"
+
+ pEval->parseOk();
+#line 1252 "grammar.c"
/*********** End %parse_accept code *******************************************/
ParseARG_STORE /* Suppress warning about unused %extra_argument variable */
ParseCTX_STORE
@@ -1067,10 +1449,11 @@ void Parse(
*/
int ParseFallback(int iToken){
#ifdef YYFALLBACK
- assert( iToken<(int)(sizeof(yyFallback)/sizeof(yyFallback[0])) );
- return yyFallback[iToken];
+ if( iToken<(int)(sizeof(yyFallback)/sizeof(yyFallback[0])) ){
+ return yyFallback[iToken];
+ }
#else
(void)iToken;
- return 0;
#endif
+ return 0;
}