From 691e471776ef0b8ba0be2166ad7e5d9066d6cd62 Mon Sep 17 00:00:00 2001 From: "Jay Freeman (saurik)" Date: Mon, 26 Oct 2009 20:23:24 +0000 Subject: [PATCH] Checkpointing syntax work on E4X before temporarily abandoning it. --- Cycript.l.in | 100 ++++++++++++++++++--- Cycript.y.in | 244 +++++++++++++++++++++++++++++++++++++++------------ E4X.hpp | 59 +++++++++++++ Library.mm | 7 +- Parser.hpp | 10 ++- 5 files changed, 348 insertions(+), 72 deletions(-) create mode 100644 E4X.hpp diff --git a/Cycript.l.in b/Cycript.l.in index ec2befc..70d608f 100644 --- a/Cycript.l.in +++ b/Cycript.l.in @@ -30,7 +30,7 @@ typedef cy::parser::token tk; yyextra->state_ = CYNewLine; \ } -#define M { \ +#define V(more) { \ if (const char *nl = reinterpret_cast(memchr(yytext, '\n', yyleng))) { \ unsigned lines(0); \ size_t left; \ @@ -42,7 +42,7 @@ typedef cy::parser::token tk; yylloc->end.lines(lines); \ yylloc->end.columns(left); \ yylloc->step(); \ - N \ + more \ } else L \ } @@ -86,6 +86,7 @@ int H(char c) { %option nounput %option interactive %option reentrant +%option stack Exponent [eE][+-]?[0-9]+ Escape \\[\\'"bfnrtv]|\\0|\\x[0-9a-fA-F]{2}|\\u[0-9a-fA-F]{4}|\\\n @@ -101,27 +102,56 @@ RegularExpressionFlags {IdentifierPart}* RegularExpressionChars {RegularExpressionChar}* RegularExpressionBody {RegularExpressionFirstChar}{RegularExpressionChars} +@begin E4X +XMLNameStart [a-zA-Z_:] +XMLNamePart [a-zA-Z0-9.-_:] +XMLName {XMLNameStart}{XMLNamePart}* +@end + %s Div %s RegExp +@begin E4X +%x XMLContent +%x XMLTag +@end + %% \/{RegularExpressionBody}\/{RegularExpressionFlags} E("") \/\/[^\n]* L -\/\*(\n|[^\*]|\*[^/])*\*\/ M +\/\*(\n|[^\*]|\*[^/])*\*\/ V(N) @begin E4X -\ -\])*]]> -\])*?> +"<>" L return tk::LeftRight; +"" L return tk::LeftSlashRight; + +\])*]]> V() return tk::XMLCDATA; +\ V() return tk::XMLComment; +\])*?> V() return tk::XMLPI; + +"=" L return tk::Equal; +">" L return tk::Right; +"/>" L return tk::SlashRight; +"{" L return tk::OpenBrace; + +\"(\n|[^"])*\"|'(\n|[^'])*' V() { + return tk::XMLAttributeValue; +} + +{XMLName} L return tk::XMLName; +[ \t\r\n] V() return tk::XMLWhitespace; +"{" L return tk::OpenBrace; +"<" L return tk::Left; +"" L C return tk::LeftRight; -"" L C return tk::LeftSlashRight; ".." L C return tk::PeriodPeriod; -"/>" L C return tk::SlashRight; @end "&" L C return tk::Ampersand; @@ -256,6 +286,11 @@ RegularExpressionBody {RegularExpressionFirstChar}{RegularExpressionChars} "each" L C yylval->identifier_ = new(yyextra->pool_) CYIdentifier("each"); return tk::Each; +@begin E4X +"namespace" L C yylval->identifier_ = new(yyextra->pool_) CYIdentifier("namespace"); return tk::Namespace; +"xml" L C yylval->identifier_ = new(yyextra->pool_) CYIdentifier("xml"); return tk::XML; +@end + {IdentifierStart}{IdentifierPart}* L C yylval->identifier_ = new(yyextra->pool_) CYIdentifier(apr_pstrmemdup(yyextra->pool_, yytext, yyleng)); return tk::Identifier_; (\.[0-9]+|(0|[1-9][0-9]*)(\.[0-9]*)?){Exponent}? L C yylval->number_ = new(yyextra->pool_) CYNumber(strtod(yytext, NULL)); return tk::NumericLiteral; @@ -323,14 +358,59 @@ void CYDriver::ScannerDestroy() { cylex_destroy(scanner_); } -void CYDriver::BeginCondition(Condition condition) { +CYDriver::Condition CYDriver::GetCondition() { + switch (yy_top_state(scanner_)) { + case RegExp: + return RegExpCondition; +@begin E4X + case XMLContent: + return XMLContentCondition; + case XMLTag: + return XMLTagCondition; +@end + default: + _assert(false); + } +} + +void CYDriver::SetCondition(Condition condition) { struct yyguts_t *yyg(reinterpret_cast(scanner_)); switch (condition) { case RegExpCondition: BEGIN(RegExp); break; +@begin E4X + case XMLContentCondition: + BEGIN(XMLContent); + break; + case XMLTagCondition: + BEGIN(XMLTag); + break; +@end default: _assert(false); } } + +void CYDriver::PushCondition(Condition condition) { + switch (condition) { + case RegExpCondition: + yy_push_state(RegExp, scanner_); + break; +@begin E4X + case XMLContentCondition: + yy_push_state(XMLContent, scanner_); + break; + case XMLTagCondition: + yy_push_state(XMLTag, scanner_); + break; +@end + default: + _assert(false); + } +} + +void CYDriver::PopCondition() { + yy_pop_state(scanner_); +} diff --git a/Cycript.y.in b/Cycript.y.in index e770815..446daf0 100644 --- a/Cycript.y.in +++ b/Cycript.y.in @@ -50,6 +50,10 @@ #include "ObjectiveC.hpp" @end +@begin E4X +#include "E4X.hpp" +@end + typedef struct { bool newline_; @@ -96,6 +100,10 @@ typedef struct { CYMessageParameter *messageParameter_; CYSelectorPart *selector_; @end + +@begin E4X + CYAttribute *attribute_; +@end }; } YYSTYPE; @@ -125,15 +133,27 @@ int cylex(YYSTYPE *lvalp, cy::location *llocp, void *scanner); %lex-param { void *scanner } @begin E4X -%token At "@" -%token ColonColon "::" -%token LeftRight "<>" -%token LeftSlashRight "" -%token PeriodPeriod ".." - %token XMLCDATA %token XMLComment %token XMLPI + +%token XMLAttributeValue +%token XMLName +%token XMLTagCharacters +%token XMLText +%token XMLWhitespace +@end + +@begin E4X +%token LeftRight "<>" +%token LeftSlashRight "" + +%token SlashRight "/>" +%token LeftSlash " Each "each" +@begin E4X +// E4X Conditional +%token Namespace "namespace" +%token XML "xml" +@end + %token Identifier_ %token NumericLiteral %token StringLiteral @@ -451,6 +477,28 @@ int cylex(YYSTYPE *lvalp, cy::location *llocp, void *scanner); %type WordOpt @end +@begin E4X +%type PropertyIdentifier_ +%type PropertySelector +%type PropertySelector_ +%type QualifiedIdentifier +%type QualifiedIdentifier_ +%type WildcardIdentifier +%type XMLComment +%type XMLCDATA +%type XMLElement +%type XMLElementContent +%type XMLMarkup +%type XMLPI + +%type AttributeIdentifier +%type DefaultXMLNamespaceStatement +%type PropertyIdentifier +%type XMLListInitialiser +%type XMLInitialiser +@end + +/* %left "*" "/" "%" %left "+" "-" %left "<<" ">>" ">>>" @@ -463,6 +511,7 @@ int cylex(YYSTYPE *lvalp, cy::location *llocp, void *scanner); %left "||" %right "=" "*=" "/=" "%=" "+=" "-=" "<<=" ">>=" ">>>=" "&=" "^=" "|=" +*/ %nonassoc "if" %nonassoc "else" @@ -471,6 +520,12 @@ int cylex(YYSTYPE *lvalp, cy::location *llocp, void *scanner); %% +/* Lexer State {{{ */ +LexSetRegExp + : { driver.SetCondition(CYDriver::RegExpCondition); } + ; +/* }}} */ + StrictSemi : { driver.Warning(yylloc, "warning, automatic semi-colon insertion required"); } ; @@ -617,12 +672,8 @@ PrimaryExpressionNoBF_ | "(" Expression ")" { $$ = $2; } ; -LexBeginRegExp - : { driver.BeginCondition(CYDriver::RegExpCondition); } - ; - PrimaryExpression - : LexBeginRegExp PrimaryExpression_ { $$ = $2; } + : LexSetRegExp PrimaryExpression_ { $$ = $2; } ; PrimaryExpressionNoBF @@ -640,12 +691,12 @@ Element ElementOpt : Element { $$ = $1; } - | LexBeginRegExp { $$ = NULL; } + | LexSetRegExp { $$ = NULL; } ; ElementListOpt : ElementList { $$ = $1; } - | LexBeginRegExp { $$ = NULL; } + | LexSetRegExp { $$ = NULL; } ; ElementList @@ -693,7 +744,7 @@ MemberExpression : PrimaryExpression { $$ = $1; } | FunctionExpression { $$ = $1; } | MemberExpression MemberAccess { $2->SetLeft($1); $$ = $2; } - | LexBeginRegExp MemberExpression_ { $$ = $2; } + | LexSetRegExp MemberExpression_ { $$ = $2; } ; MemberExpressionNoBF @@ -708,7 +759,7 @@ NewExpression_ NewExpression : MemberExpression { $$ = $1; } - | LexBeginRegExp NewExpression_ { $$ = $2; } + | LexSetRegExp NewExpression_ { $$ = $2; } ; NewExpressionNoBF @@ -735,7 +786,7 @@ ArgumentList_ ArgumentListOpt : ArgumentList { $$ = $1; } - | LexBeginRegExp { $$ = NULL; } + | LexSetRegExp { $$ = NULL; } ; ArgumentList @@ -786,7 +837,7 @@ UnaryExpression_ UnaryExpression : PostfixExpression { $$ = $1; } - | LexBeginRegExp UnaryExpression_ { $$ = $2; } + | LexSetRegExp UnaryExpression_ { $$ = $2; } ; UnaryExpressionNoBF @@ -1002,7 +1053,7 @@ AssignmentExpression_ AssigneeExpression : LeftHandSideExpression { $$ = $1; } - | LexBeginRegExp UnaryAssigneeExpression { $$ = $2; } + | LexSetRegExp UnaryAssigneeExpression { $$ = $2; } ; AssigneeExpressionNoBF @@ -1049,12 +1100,12 @@ ExpressionNoIn_ ExpressionOpt : Expression { $$ = $1; } - | LexBeginRegExp { $$ = NULL; } + | LexSetRegExp { $$ = NULL; } ; ExpressionNoInOpt : ExpressionNoIn { $$ = $1; } - | LexBeginRegExp { $$ = NULL; } + | LexSetRegExp { $$ = NULL; } ; Expression @@ -1089,7 +1140,7 @@ Statement_ ; Statement - : LexBeginRegExp Statement_ { $$ = $2; } + : LexSetRegExp Statement_ { $$ = $2; } ; /* }}} */ /* 12.1 Block {{{ */ @@ -1107,7 +1158,7 @@ StatementList StatementListOpt : StatementList { $$ = $1; } - | LexBeginRegExp { $$ = NULL; } + | LexSetRegExp { $$ = NULL; } ; /* }}} */ /* 12.2 Variable Statement {{{ */ @@ -1205,7 +1256,7 @@ ForStatement ForStatementInitialiser : ExpressionNoInOpt { $$ = $1; } - | LexBeginRegExp "var" VariableDeclarationListNoIn { $$ = $3; } + | LexSetRegExp "var" VariableDeclarationListNoIn { $$ = $3; } ; /* }}} */ /* 12.6.4 The for-in Statement {{{ */ @@ -1215,7 +1266,7 @@ ForInStatement ForInStatementInitialiser : LeftHandSideExpression { $$ = $1; } - | LexBeginRegExp "var" VariableDeclarationNoIn { $$ = $3; } + | LexSetRegExp "var" VariableDeclarationNoIn { $$ = $3; } ; /* }}} */ @@ -1295,7 +1346,7 @@ FunctionDeclaration ; FunctionExpression - : LexBeginRegExp "function" IdentifierOpt "(" FormalParameterList ")" "{" FunctionBody "}" { $$ = new(driver.pool_) CYFunctionExpression($3, $5, $8); } + : LexSetRegExp "function" IdentifierOpt "(" FormalParameterList ")" "{" FunctionBody "}" { $$ = new(driver.pool_) CYFunctionExpression($3, $5, $8); } ; FormalParameterList_ @@ -1319,7 +1370,7 @@ Program SourceElements : SourceElement SourceElements { $1->SetNext($2); $$ = $1; } - | LexBeginRegExp { $$ = NULL; } + | LexSetRegExp { $$ = NULL; } ; SourceElement_ @@ -1328,7 +1379,7 @@ SourceElement_ ; SourceElement - : LexBeginRegExp SourceElement_ { $$ = $2; } + : LexSetRegExp SourceElement_ { $$ = $2; } ; /* }}} */ @@ -1336,7 +1387,7 @@ SourceElement /* Cycript (Objective-C): @class Declaration {{{ */ ClassSuperOpt /* XXX: why the hell did I choose MemberExpressionNoBF? */ - : ":" LexBeginRegExp MemberExpressionNoBF { $$ = $3; } + : ":" LexSetRegExp MemberExpressionNoBF { $$ = $3; } | { $$ = NULL; } ; @@ -1434,7 +1485,7 @@ SelectorList MessageExpression : "[" AssignmentExpression SelectorList "]" { $$ = new(driver.pool_) CYSendDirect($2, $3); } - | "[" LexBeginRegExp "super" SelectorList "]" { $$ = new(driver.pool_) CYSendSuper($4); } + | "[" LexSetRegExp "super" SelectorList "]" { $$ = new(driver.pool_) CYSendSuper($4); } ; SelectorExpressionOpt @@ -1461,7 +1512,7 @@ PrimaryExpressionNoBF_ @begin C /* Cycript (C): Pointer Indirection/Addressing {{{ */ UnaryAssigneeExpression - : "*" UnaryExpression { $$ = new(driver.pool_) CYIndirect($2); } + : "^" UnaryExpression { $$ = new(driver.pool_) CYIndirect($2); } ; UnaryExpression_ @@ -1476,71 +1527,123 @@ MemberAccess @end @begin E4X +/* Lexer State {{{ */ +LexPushRegExp + : { driver.PushCondition(CYDriver::RegExpCondition); } + ; + +LexPushXMLContent + : { driver.PushCondition(CYDriver::XMLContentCondition); } + ; + +LexPushXMLTag + : { driver.PushCondition(CYDriver::XMLTagCondition); } + ; + +LexPop + : { driver.PopCondition(); } + ; + +LexSetXMLContent + : { driver.SetCondition(CYDriver::XMLContentCondition); } + ; + +LexSetXMLTag + : { driver.SetCondition(CYDriver::XMLTagCondition); } + ; +/* }}} */ + +XMLWhitespaceOpt + : XMLWhitespace + | + ; + +/* 8.1 Context Keywords {{{ */ +Identifier + : "namespace" { $$ = $1; } + | "xml" { $$ = $1; } + ; +/* }}} */ /* 8.3 XML Initialiser Input Elements {{{ */ XMLMarkup - : XMLComment - | XMLCDATA - | XMLPI + : XMLComment { $$ = $1; } + | XMLCDATA { $$ = $1; } + | XMLPI { $$ = $1; } ; /* }}} */ /* 11.1 Primary Expressions {{{ */ PrimaryExpressionNoBF_ - : PropertyIdentifier - | XMLInitialiser - | XMLListInitialiser + : PropertyIdentifier { $$ = $1; } + | XMLInitialiser { $$ = $1; } + | XMLListInitialiser { $$ = $1; } ; PropertyIdentifier - : AttributeIdentifier - | QualifiedIdentifier - | WildcardIdentifier + : AttributeIdentifier { $$ = $1; } + | QualifiedIdentifier { $$ = $1; } + | WildcardIdentifier { $$ = $1; } ; /* }}} */ /* 11.1.1 Attribute Identifiers {{{ */ AttributeIdentifier - : "@" PropertySelector - | "@" QualifiedIdentifier - | "@" "[" Expression "]" + : "@" QualifiedIdentifier_ { $$ = new(driver.pool_) CYAttribute($2); } + ; + +PropertySelector_ + : PropertySelector + | "[" Expression "]" ; PropertySelector - : Identifier - | WildcardIdentifier + : Word { $$ = $1; } + | WildcardIdentifier { $$ = $1; } ; /* }}} */ /* 11.1.2 Qualified Identifiers {{{ */ +QualifiedIdentifier_ + : PropertySelector_ { $$ = $1; } + | QualifiedIdentifier { $$ = $1; } + ; + QualifiedIdentifier - : PropertySelector "::" PropertySelector - | PropertySelector "::" "[" Expression "]" + : PropertySelector "::" PropertySelector_ { $$ = new(driver.pool_) CYQName($1, $3); } ; /* }}} */ /* 11.1.3 Wildcard Identifiers {{{ */ WildcardIdentifier - : "*" + : "*" { $$ = new(driver.pool_) CYWildcard(); } ; /* }}} */ /* 11.1.4 XML Initialiser {{{ */ XMLInitialiser - : XMLMarkup - | XMLElement + : XMLMarkup { $$ = $1; } + | XMLElement { $$ = $1; } ; XMLElement - : "<" XMLTagContent XMLWhitespaceOpt "/>" - | "<" XMLTagContent XMLWhitespace ">" XMLElementContentOpt "" + : "<" XMLTagContent_ "/>" LexPop + | "<" XMLTagContent_ ">" LexSetXMLContent XMLElementContentOpt "" LexPop + ; + +XMLTagContent_ + : LexPushXMLTag XMLTagContent XMLWhitespaceOpt ; XMLTagContent : XMLTagName XMLAttributesOpt ; +XMLExpression + : "{" LexPushRegExp Expression "}" LexPop + ; + XMLTagName - : "{" Expression "}" + : XMLExpression | XMLName ; XMLAttributes - : XMLWhitespace "{" Expression "}" + : XMLWhitespace XMLExpression | XMLAttributeOpt XMLAttributes ; @@ -1549,9 +1652,13 @@ XMLAttributesOpt | ; +XMLAttributeValue_ + : XMLExpression + | XMLAttributeValue + ; + XMLAttribute - : XMLWhitespace XMLName XMLWhitespaceOpt "=" XMLWhitespaceOpt "{" Expression "}" - | XMLWhitespace XMLName XMLWhitespaceOpt "=" XMLWhitespaceOpt XMLAttributeValue + : XMLWhitespace XMLName XMLWhitespaceOpt "=" XMLWhitespaceOpt XMLAttributeValue_ ; XMLAttributeOpt @@ -1560,7 +1667,7 @@ XMLAttributeOpt ; XMLElementContent - : "{" Expression "}" XMLElementContentOpt + : XMLExpression XMLElementContentOpt | XMLMarkup XMLElementContentOpt | XMLText XMLElementContentOpt | XMLElement XMLElementContentOpt @@ -1573,7 +1680,28 @@ XMLElementContentOpt /* }}} */ /* 11.1.5 XMLList Initialiser {{{ */ XMLListInitialiser - : "<>" XMLElementContent "" + : "<>" LexPushXMLContent XMLElementContent "" LexPop { $$ = new(driver.pool_) CYXMLList($3); } + ; +/* }}} */ +/* 11.2 Left-Hand-Side Expressions {{{ */ +PropertyIdentifier_ + : Word { $$ = $1; } + | PropertyIdentifier { $$ = $1; } + ; + +MemberAccess + : "." PropertyIdentifier { $$ = new(driver.pool_) CYPropertyMember(NULL, $2); } + | ".." PropertyIdentifier_ { $$ = new(driver.pool_) CYDescendantMember(NULL, $2); } + | "." "(" Expression ")" { $$ = new(driver.pool_) CYFilteringPredicate(NULL, $3); } + ; +/* }}} */ +/* 12.1 The default xml namespace Statement {{{ */ +DefaultXMLNamespaceStatement + : "default" "xml" "namespace" "=" Expression Terminator { $$ = new(driver.pool_) CYDefaultXMLNamespace($5); } + ; + +Statement_ + : DefaultXMLNamespaceStatement { $$ = $1; } ; /* }}} */ @end @@ -1623,7 +1751,7 @@ Statement_ *//* }}} */ /* JavaScript FTW: Function Statements {{{ */ Statement - : LexBeginRegExp FunctionDeclaration { driver.Warning(yylloc, "warning, FunctionDeclaration is a SourceElement, not a Statement"); } { $$ = $2; } + : LexSetRegExp FunctionDeclaration { driver.Warning(yylloc, "warning, FunctionDeclaration is a SourceElement, not a Statement"); } { $$ = $2; } ; /* }}} */ diff --git a/E4X.hpp b/E4X.hpp new file mode 100644 index 0000000..4e3b156 --- /dev/null +++ b/E4X.hpp @@ -0,0 +1,59 @@ +/* Cycript - Remote Execution Server and Disassembler + * Copyright (C) 2009 Jay Freeman (saurik) +*/ + +/* Modified BSD License {{{ */ +/* + * Redistribution and use in source and binary + * forms, with or without modification, are permitted + * provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the + * above copyright notice, this list of conditions + * and the following disclaimer. + * 2. Redistributions in binary form must reproduce the + * above copyright notice, this list of conditions + * and the following disclaimer in the documentation + * and/or other materials provided with the + * distribution. + * 3. The name of the author may not be used to endorse + * or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, + * BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF + * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR + * TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +*/ +/* }}} */ + +#ifndef CYCRIPT_E4X_HPP +#define CYCRIPT_E4X_HPP + +#include "Parser.hpp" + +struct CYDefaultXMLNamespace : + CYStatement +{ + CYExpression *expression_; + + CYDefaultXMLNamespace(CYExpression *expression) : + expression_(expression) + { + } + + virtual CYStatement *Replace(CYContext &context); + virtual void Output(CYOutput &out, CYFlags flags) const; +}; + +#endif/*CYCRIPT_E4X_HPP*/ diff --git a/Library.mm b/Library.mm index bef1661..81e80e5 100644 --- a/Library.mm +++ b/Library.mm @@ -2043,8 +2043,10 @@ static CYUTF16String CYCastUTF16String(JSStringRef value) { return CYUTF16String(JSStringGetCharactersPtr(value), JSStringGetLength(value)); } -// XXX: sometimes pool is null static CYUTF8String CYPoolUTF8String(apr_pool_t *pool, JSStringRef value) { + if (pool == NULL) + return CYCastUTF8String(CYCastNSString(NULL, value)); + CYUTF16String utf16(CYCastUTF16String(value)); const char *in(reinterpret_cast(utf16.data)); @@ -3325,7 +3327,8 @@ static JSValueRef Type_getProperty(JSContextRef context, JSObjectRef object, JSS type.primitive = sig::pointer_P; type.data.data.size = 0; } else { - size_t index(CYGetIndex(NULL, property)); + CYPool pool; + size_t index(CYGetIndex(pool, property)); if (index == _not(size_t)) return NULL; type.primitive = sig::array_P; diff --git a/Parser.hpp b/Parser.hpp index 63aa17a..87dc682 100644 --- a/Parser.hpp +++ b/Parser.hpp @@ -311,6 +311,8 @@ class CYDriver { enum Condition { RegExpCondition, + XMLContentCondition, + XMLTagCondition, }; std::string filename_; @@ -334,7 +336,11 @@ class CYDriver { CYDriver(const std::string &filename); ~CYDriver(); - void BeginCondition(Condition condition); + Condition GetCondition(); + void SetCondition(Condition condition); + + void PushCondition(Condition condition); + void PopCondition(); void Warning(const cy::location &location, const char *message); }; @@ -1472,7 +1478,7 @@ struct CYIndirect : } virtual const char *Operator() const { - return "*"; + return "^"; } CYAlphabetic(false) -- 2.45.2