From e53322782610fa076081d974ac22712107a2fe0e Mon Sep 17 00:00:00 2001 From: "Jay Freeman (saurik)" Date: Fri, 4 Sep 2009 16:40:46 +0000 Subject: [PATCH 1/1] OMG it compiles. --- Cycript.l | 87 +++++++++++++ Cycript.y | 95 +++++++++++++++ Library.mm | 350 +++-------------------------------------------------- Parser.dat | 67 ++++++++++ Parser.hpp | 2 + Parser.py | 100 +++++++++++++++ makefile | 15 ++- 7 files changed, 378 insertions(+), 338 deletions(-) create mode 100644 Cycript.l create mode 100644 Cycript.y create mode 100644 Parser.dat create mode 100644 Parser.hpp create mode 100755 Parser.py diff --git a/Cycript.l b/Cycript.l new file mode 100644 index 0000000..10be43f --- /dev/null +++ b/Cycript.l @@ -0,0 +1,87 @@ +%{ +#include "Cycript.tab.h" +%} + +%option prefix="cy" +%option bison-bridge +%option bison-locations +%option noyywrap +%option yylineno +%option nounput +%option interactive + +delim [ \t] +whitesp {delim}+ +digit [0-9] +number [-]?{digit}*[.]?{digit}+ + +%% + +"&" { return CYTokenAmpersand; } +"&&" { return CYTokenAmpersandAmpersand; } +"&=" { return CYTokenAmpersandEqual; } +"^" { return CYTokenCarrot; } +"^=" { return CYTokenCarrotEqual; } +"=" { return CYTokenEqual; } +"==" { return CYTokenEqualEqual; } +"===" { return CYTokenEqualEqualEqual; } +"!" { return CYTokenExclamation; } +"!=" { return CYTokenExclamationEqual; } +"!==" { return CYTokenExclamationEqualEqual; } +"-" { return CYTokenHyphen; } +"-=" { return CYTokenHyphenEqual; } +"--" { return CYTokenHyphenHyphen; } +"->" { return CYTokenHyphenRight; } +"<" { return CYTokenLeft; } +"<=" { return CYTokenLeftEqual; } +"<<" { return CYTokenLeftLeft; } +"<<=" { return CYTokenLeftLeftEqual; } +"%" { return CYTokenPercent; } +"%=" { return CYTokenPercentEqual; } +"." { return CYTokenPeriod; } +"|" { return CYTokenPipe; } +"|=" { return CYTokenPipeEqual; } +"||" { return CYTokenPipePipe; } +"+" { return CYTokenPlus; } +"+=" { return CYTokenPlusEqual; } +"++" { return CYTokenPlusPlus; } +">" { return CYTokenRight; } +">=" { return CYTokenRightEqual; } +">>" { return CYTokenRightRight; } +">>=" { return CYTokenRightRightEqual; } +">>>" { return CYTokenRightRightRight; } +">>>=" { return CYTokenRightRightRightEqual; } +"/" { return CYTokenSlash; } +"/=" { return CYTokenSlashEqual; } +"*" { return CYTokenStar; } +"*=" { return CYTokenStarEqual; } +"~" { return CYTokenTilde; } + +"break" { return CYTokenBreak; } +"case" { return CYTokenCase; } +"catch" { return CYTokenCatch; } +"continue" { return CYTokenContinue; } +"default" { return CYTokenDefault; } +"delete" { return CYTokenDelete; } +"do" { return CYTokenDo; } +"else" { return CYTokenElse; } +"false" { return CYTokenFalse; } +"finally" { return CYTokenFinally; } +"for" { return CYTokenFor; } +"function" { return CYTokenFunction; } +"if" { return CYTokenIf; } +"in" { return CYTokenIn; } +"instanceof" { return CYTokenInstanceOf; } +"new" { return CYTokenNew; } +"null" { return CYTokenNull; } +"return" { return CYTokenReturn; } +"switch" { return CYTokenSwitch; } +"this" { return CYTokenThis; } +"throw" { return CYTokenThrow; } +"true" { return CYTokenTrue; } +"try" { return CYTokenTry; } +"typeof" { return CYTokenTypeOf; } +"var" { return CYTokenVar; } +"void" { return CYTokenVoid; } +"while" { return CYTokenWhile; } +"with" { return CYTokenWith; } diff --git a/Cycript.y b/Cycript.y new file mode 100644 index 0000000..71da89e --- /dev/null +++ b/Cycript.y @@ -0,0 +1,95 @@ +%{ +#include "Parser.hpp" +#include "Cycript.tab.h" +void cyerror(YYLTYPE *locp, CYParser *context, const char *msg); +int cylex(YYSTYPE *lvalp, YYLTYPE *llocp); +%} + +%pure-parser +%name-prefix="cy" +%locations +%defines +%error-verbose + +%parse-param { CYParser *context } + +%token CYTokenAmpersand "&" +%token CYTokenAmpersandAmpersand "&&" +%token CYTokenAmpersandEqual "&=" +%token CYTokenCarrot "^" +%token CYTokenCarrotEqual "^=" +%token CYTokenEqual "=" +%token CYTokenEqualEqual "==" +%token CYTokenEqualEqualEqual "===" +%token CYTokenExclamation "!" +%token CYTokenExclamationEqual "!=" +%token CYTokenExclamationEqualEqual "!==" +%token CYTokenHyphen "-" +%token CYTokenHyphenEqual "-=" +%token CYTokenHyphenHyphen "--" +%token CYTokenHyphenRight "->" +%token CYTokenLeft "<" +%token CYTokenLeftEqual "<=" +%token CYTokenLeftLeft "<<" +%token CYTokenLeftLeftEqual "<<=" +%token CYTokenPercent "%" +%token CYTokenPercentEqual "%=" +%token CYTokenPeriod "." +%token CYTokenPipe "|" +%token CYTokenPipeEqual "|=" +%token CYTokenPipePipe "||" +%token CYTokenPlus "+" +%token CYTokenPlusEqual "+=" +%token CYTokenPlusPlus "++" +%token CYTokenRight ">" +%token CYTokenRightEqual ">=" +%token CYTokenRightRight ">>" +%token CYTokenRightRightEqual ">>=" +%token CYTokenRightRightRight ">>>" +%token CYTokenRightRightRightEqual ">>>=" +%token CYTokenSlash "/" +%token CYTokenSlashEqual "/=" +%token CYTokenStar "*" +%token CYTokenStarEqual "*=" +%token CYTokenTilde "~" + +%token CYTokenBreak "break" +%token CYTokenCase "case" +%token CYTokenCatch "catch" +%token CYTokenContinue "continue" +%token CYTokenDefault "default" +%token CYTokenDelete "delete" +%token CYTokenDo "do" +%token CYTokenElse "else" +%token CYTokenFalse "false" +%token CYTokenFinally "finally" +%token CYTokenFor "for" +%token CYTokenFunction "function" +%token CYTokenIf "if" +%token CYTokenIn "in" +%token CYTokenInstanceOf "instanceof" +%token CYTokenNew "new" +%token CYTokenNull "null" +%token CYTokenReturn "return" +%token CYTokenSwitch "switch" +%token CYTokenThis "this" +%token CYTokenThrow "throw" +%token CYTokenTrue "true" +%token CYTokenTry "try" +%token CYTokenTypeOf "typeof" +%token CYTokenVar "var" +%token CYTokenVoid "void" +%token CYTokenWhile "while" +%token CYTokenWith "with" + +%% + +hello: ; + +%% + +#include + +void cyerror(YYLTYPE *locp, CYParser *context, const char *msg) { + fprintf(stderr, "err:%s\n", msg); +} diff --git a/Library.mm b/Library.mm index aa0b42c..ee77879 100644 --- a/Library.mm +++ b/Library.mm @@ -74,6 +74,8 @@ #include #include +#include "Parser.hpp" + #undef _assert #undef _trace @@ -161,6 +163,14 @@ class CYPool { operator apr_pool_t *() const { return pool_; } + + char *operator ()(const char *data) const { + return apr_pstrdup(pool_, data); + } + + char *operator ()(const char *data, size_t size) const { + return apr_pstrndup(pool_, data, size); + } }; /* }}} */ @@ -991,274 +1001,13 @@ static JSStaticValue Pointer_staticValues[2] = { {NULL, NULL, NULL, 0} }; -enum CYTokenType { - CYTokenBreak, CYTokenCase, CYTokenCatch, CYTokenContinue, CYTokenDefault, - CYTokenDelete, CYTokenDo, CYTokenElse, CYTokenFinally, CYTokenFor, - CYTokenFunction, CYTokenIf, CYTokenIn, CYTokenInstanceOf, CYTokenNew, - CYTokenReturn, CYTokenSwitch, CYTokenThis, CYTokenThrow, CYTokenTry, - CYTokenTypeOf, CYTokenVar, CYTokenVoid, CYTokenWhile, CYTokenWith, - - CYTokenOpenBrace, CYTokenOpenParen, CYTokenOpenBracket, - CYTokenCloseBrace, CYTokenCloseParen, CYTokenCloseBracket, - - CYTokenPeriod, CYTokenSemiColon, CYTokenComma, CYTokenLeft, CYTokenRight, - CYTokenLeftEqual, CYTokenRightEqual, CYTokenEqualEqual, CYTokenExclamationEqual, - CYTokenEqualEqualEqual, CYTokenExclamationEqualEqual, CYTokenPlus, CYTokenHyphen, - CYTokenStar, CYTokenPercent, CYTokenPlusPlus, CYTokenHyphenHyphen, CYTokenLeftLeft, - CYTokenRightRight, CYTokenRightRightRight, CYTokenAmpersand, CYTokenPipe, - CYTokenCarrot, CYTokenExclamation, CYTokenTilde, CYTokenAmpersandAmpersand, - CYTokenPipePipe, CYTokenQuestion, CYTokenColon, CYTokenEqual, CYTokenPlusEqual, - CYTokenHyphenEqual, CYTokenStarEqual, CYTokenPercentEqual, CYTokenLeftLeftEqual, - CYTokenRightRightEqual, CYTokenRightRightRightEqual, CYTokenAmpersandEqual, - CYTokenPipeEqual, CYTokenCarrotEqual, CYTokenSlash, CYTokenSlashEqual, - - CYTokenIdentifier, CYTokenLiteral -}; - -typedef std::map TokenMap; -TokenMap Tokens_; - -struct CYToken { - enum CYTokenType type_; - char *value_; - CYToken *next_; - CYToken **prev_; -}; - -struct CYExpression { -}; - -struct CYRange { - uint64_t lo_; - uint64_t hi_; - - CYRange(uint64_t lo, uint64_t hi) : - lo_(lo), hi_(hi) - { - } - - bool operator [](uint8_t value) const { - return !(value >> 7) && (value >> 6 ? hi_ : lo_) >> (value & 0x3f) & 0x1; - } - - void operator()(uint8_t value) { - if (value >> 7) - return; - (value >> 6 ? hi_ : lo_) |= uint64_t(0x1) << (value & 0x3f); - } -}; - -CYRange WordStartRange_(0x1000000000LLU,0x7fffffe87fffffeLLU); // A-Za-z_$ -CYRange WordEndRange_(0x3ff001000000000LLU,0x7fffffe87fffffeLLU); // A-Za-z_$0-9 -CYRange NumberRange_(0x3ff400000000000LLU,0x100007e0100007eLLU); // 0-9.eExXA-Fa-f -CYRange PunctuationRange_(0xfc00fc6200000000LLU,0x5000000040000000LLU); // -.,;<>=!+*/%&|^~?: - -struct CStringMapLess : - std::binary_function -{ - _finline bool operator ()(const char *lhs, const char *rhs) const { - return strcmp(lhs, rhs) < 0; - } -}; - -std::set OperatorWords_; - -struct CYParser { - FILE *fin_; - FILE *fout_; - - size_t capacity_; - char *data_; - - size_t offset_; - size_t size_; - - CYParser(FILE *fin, FILE *fout) : - fin_(fin), - fout_(fout), - capacity_(1024), - data_(reinterpret_cast(malloc(capacity_))), - offset_(0), - size_(0) - { - } - - ~CYParser() { - // XXX: this will not deconstruct in constructor failures - free(data_); - } - - bool ReadLine(const char *prompt) { - offset_ = 0; - data_[capacity_ - 1] = ~'\0'; - - start: - if (fout_ != NULL) { - fputs(prompt, fout_); - fputs(" ", fout_); - fflush(fout_); - } - - if (fgets(data_, capacity_, fin_) == NULL) - return false; - - check: - if (data_[capacity_ - 1] != '\0') { - size_ = strlen(data_); - if (size_ == 0) - goto start; - if (data_[size_ - 1] == '\n') { - --size_; - goto newline; - } - } else if (data_[capacity_ - 2] == '\n') { - size_ = capacity_ - 2; - newline: - data_[size_] = '\0'; - } else { - size_t capacity(capacity_ * 2); - char *data(reinterpret_cast(realloc(data_, capacity))); - _assert(data != NULL); - data_ = data; - size_ = capacity_ - 1; - capacity_ = capacity; - fgets(data_ + size_, capacity_ - size_, fin_); - goto check; - } - - return true; - } - - _finline void ScanRange(const CYRange &range) { - while (range[data_[++offset_]]); - } - - CYToken *ParseToken(apr_pool_t *pool, const char *prompt) { - char next; - - for (;;) { - if (offset_ == size_ && (prompt == NULL || !ReadLine(prompt))) - return false; - next = data_[offset_]; - if (next != ' ' && next != '\t') - break; - ++offset_; - } - - CYTokenType type; - size_t index(offset_); - - if (WordStartRange_[next]) { - ScanRange(WordEndRange_); - type = CYTokenWord; - } else if (next == '.') { - char after(data_[offset_ + 1]); - if (after >= '0' && next <= '9') - goto number; - goto punctuation; - } else if (next >= '0' && next <= '9') { - number: - ScanRange(NumberRange_); - type = CYTokenLiteral; - } else if (PunctuationRange_[next]) { - punctuation: - ScanRange(PunctuationRange_); - type = CYTokenPunctuation; - } else if (next == '"' || next == '\'') { - for (;;) { - char after(data_[++offset_]); - if (after == '\\') { - after = data_[offset_]; - _assert(after != '\0'); - if (after == 'u') { - offset_ += 4; - _assert(offset_ < size_); - } - } else if (after == next) - break; - } - - ++offset_; - type = CYTokenLiteral; - } else if (next == '(' || next == '{' || next == '[') { - ++offset_; - type = CYTokenOpen; - } else if (next == ')' || next == '}' || next == ']') { - ++offset_; - type = CYTokenClose; - } else if (next == ';') { - ++offset_; - type = CYTokenSemiColon; - } else { - printf(":( %u\n", next); - _assert(false); - } - - char *value(apr_pstrndup(pool, data_ + index, offset_ - index)); - - if (type == CYTokenWord && OperatorWords_.find(value) != OperatorWords_.end()) - type = CYTokenPunctuation; - - CYToken *token(new(pool) CYToken()); - token->type_ = type; - token->value_ = value; - token->next_ = token; - token->prev_ = &token->next_; - return token; - } - - CYToken *ParseExpression(apr_pool_t *pool, const char *prompt) { - CYToken *token(ParseToken(pool, prompt)); - return token; - } -}; +void cyparse(CYParser *parser); +extern int cydebug; void CYConsole(FILE *fin, FILE *fout, FILE *ferr) { - CYParser parser(fin, fout); - - for (;;) { _pooled - CYPool pool; - CYToken *token(parser.ParseExpression(pool, ">>>")); - if (token == NULL) - return; - fputs("<", fout); - CYToken *next(token); - do { - fputs(next->value_, fout); - next = next->next_; - fputs("|", fout); - } while (next != token); - fputs(">\n", fout); -#if 0 - JSStringRef script(JSStringCreateWithUTF8CString(line.c_str())); - - JSContextRef context(JSGetContext()); - - JSValueRef exception(NULL); - JSValueRef result(JSEvaluateScript(context, script, NULL, NULL, 0, &exception)); - JSStringRelease(script); - - if (exception != NULL) - result = exception; - - if (!JSValueIsUndefined(context, result)) { - CFStringRef json; - - @try { json: - json = JSValueToJSONCopy(context, result); - } @catch (id error) { - CYThrow(context, error, &result); - goto json; - } - - fputs([reinterpret_cast(json) UTF8String], fout); - CFRelease(json); - - fputs("\n", fout); - fflush(fout); - } -#endif - } + cydebug = 1; + CYParser parser; + cyparse(&parser); } MSInitialize { _pooled @@ -1326,75 +1075,6 @@ MSInitialize { _pooled Bridge_ = [[NSMutableDictionary dictionaryWithContentsOfFile:@"/usr/lib/libcycript.plist"] retain]; - Tokens_.insert(TokenMap::value_type("break", CYTokenBreak)); - Tokens_.insert(TokenMap::value_type("case", CYTokenCase)); - Tokens_.insert(TokenMap::value_type("catch", CYTokenCatch)); - Tokens_.insert(TokenMap::value_type("continue", CYTokenContinue)); - Tokens_.insert(TokenMap::value_type("default", CYTokenDefault)); - Tokens_.insert(TokenMap::value_type("delete", CYTokenDelete)); - Tokens_.insert(TokenMap::value_type("do", CYTokenDo)); - Tokens_.insert(TokenMap::value_type("else", CYTokenElse)); - Tokens_.insert(TokenMap::value_type("finally", CYTokenFinally)); - Tokens_.insert(TokenMap::value_type("for", CYTokenFor)); - Tokens_.insert(TokenMap::value_type("function", CYTokenFunction)); - Tokens_.insert(TokenMap::value_type("if", CYTokenIf)); - Tokens_.insert(TokenMap::value_type("in", CYTokenIn)); - Tokens_.insert(TokenMap::value_type("instanceof", CYTokenInstanceOf)); - Tokens_.insert(TokenMap::value_type("new", CYTokenNew)); - Tokens_.insert(TokenMap::value_type("return", CYTokenReturn)); - Tokens_.insert(TokenMap::value_type("switch", CYTokenSwitch)); - Tokens_.insert(TokenMap::value_type("this", CYTokenThis)); - Tokens_.insert(TokenMap::value_type("throw", CYTokenThrow)); - Tokens_.insert(TokenMap::value_type("try", CYTokenTry)); - Tokens_.insert(TokenMap::value_type("typeof", CYTokenTypeOf)); - Tokens_.insert(TokenMap::value_type("var", CYTokenVar)); - Tokens_.insert(TokenMap::value_type("void", CYTokenVoid)); - Tokens_.insert(TokenMap::value_type("while", CYTokenWhile)); - Tokens_.insert(TokenMap::value_type("with", CYTokenWith)); - - Tokens_.insert(TokenMap::value_type("&", CYTokenAmpersand)); - Tokens_.insert(TokenMap::value_type("&&", CYTokenAmpersandAmpersand)); - Tokens_.insert(TokenMap::value_type("&=", CYTokenAmpersandEqual)); - Tokens_.insert(TokenMap::value_type("^", CYTokenCarrot)); - Tokens_.insert(TokenMap::value_type("^=", CYTokenCarrotEqual)); - Tokens_.insert(TokenMap::value_type(":", CYTokenColon)); - Tokens_.insert(TokenMap::value_type(",", CYTokenComma)); - Tokens_.insert(TokenMap::value_type("=", CYTokenEqual)); - Tokens_.insert(TokenMap::value_type("==", CYTokenEqualEqual)); - Tokens_.insert(TokenMap::value_type("===", CYTokenEqualEqualEqual)); - Tokens_.insert(TokenMap::value_type("!", CYTokenExclamation)); - Tokens_.insert(TokenMap::value_type("!=", CYTokenExclamationEqual)); - Tokens_.insert(TokenMap::value_type("!==", CYTokenExclamationEqualEqual)); - Tokens_.insert(TokenMap::value_type("-", CYTokenHyphen)); - Tokens_.insert(TokenMap::value_type("-=", CYTokenHyphenEqual)); - Tokens_.insert(TokenMap::value_type("--", CYTokenHyphenHyphen)); - Tokens_.insert(TokenMap::value_type("<", CYTokenLeft)); - Tokens_.insert(TokenMap::value_type("<=", CYTokenLeftEqual)); - Tokens_.insert(TokenMap::value_type("<<", CYTokenLeftLeft)); - Tokens_.insert(TokenMap::value_type("<<=", CYTokenLeftLeftEqual)); - Tokens_.insert(TokenMap::value_type("%", CYTokenPercent)); - Tokens_.insert(TokenMap::value_type("%=", CYTokenPercentEqual)); - Tokens_.insert(TokenMap::value_type(".", CYTokenPeriod)); - Tokens_.insert(TokenMap::value_type("|", CYTokenPipe)); - Tokens_.insert(TokenMap::value_type("|=", CYTokenPipeEqual)); - Tokens_.insert(TokenMap::value_type("||", CYTokenPipePipe)); - Tokens_.insert(TokenMap::value_type("+", CYTokenPlus)); - Tokens_.insert(TokenMap::value_type("+=", CYTokenPlusEqual)); - Tokens_.insert(TokenMap::value_type("++", CYTokenPlusPlus)); - Tokens_.insert(TokenMap::value_type("?", CYTokenQuestion)); - Tokens_.insert(TokenMap::value_type(">", CYTokenRight)); - Tokens_.insert(TokenMap::value_type(">=", CYTokenRightEqual)); - Tokens_.insert(TokenMap::value_type(">>", CYTokenRightRight)); - Tokens_.insert(TokenMap::value_type(">>=", CYTokenRightRightEqual)); - Tokens_.insert(TokenMap::value_type(">>>", CYTokenRightRightRight)); - Tokens_.insert(TokenMap::value_type(">>>=", CYTokenRightRightRightEqual)); - Tokens_.insert(TokenMap::value_type(";", CYTokenSemiColon)); - Tokens_.insert(TokenMap::value_type("/", CYTokenSlash)); - Tokens_.insert(TokenMap::value_type("/=", CYTokenSlashEqual)); - Tokens_.insert(TokenMap::value_type("*", CYTokenStar)); - Tokens_.insert(TokenMap::value_type("*=", CYTokenStarEqual)); - Tokens_.insert(TokenMap::value_type("~", CYTokenTilde)); - name_ = JSStringCreateWithUTF8CString("name"); message_ = JSStringCreateWithUTF8CString("message"); length_ = JSStringCreateWithUTF8CString("length"); diff --git a/Parser.dat b/Parser.dat new file mode 100644 index 0000000..86cc896 --- /dev/null +++ b/Parser.dat @@ -0,0 +1,67 @@ +& AddressOf R BitwiseAnd 5 +&& - R LogicalAnd 8 +&= - A BitwiseAnd +^ - R BitwiseXor 6 +^= - A BitwiseXor += - A +== - R Equal 4 +=== - R Identical 4 +! LogicalNot +!= - R NotEqual 4 +!== - R NotIdentical 4 +- Negate R Subtract 1 +-= - A Subtract +-- PreDecrement R PostDecrement +-> - U Indirect +< - R LessThan 3 +<= - R LessThanOrEqual 3 +<< - R LeftShift 2 +<<= - A LeftShift +% - R Modulus 0 +%= - A Modulus +. - U Direct +| - R BitwiseOr 7 +|= - A BitwiseOr +|| - R LogicalOr 9 ++ Affirm R Add 1 ++= - A Add +++ PreIncrement R PostIncrement +> - R GreaterThan 3 +>= - R GreaterThanOrEqual 3 +>> - R SignedRightShift 2 +>>= - A SignedRightShift +>>> - R UnsignedRightShift 2 +>>>= - A UnsignedRightShift +/ - R Divide 0 +/= - A Divide +* Indirect R Multiply 0 +*= - A Multiply +~ BitwiseNot +Break - +Case - +Catch - +Continue - +Default - +Delete Delete +Do - +Else - +False - L +Finally - +For - +Function - +If - +In - R In 3 +InstanceOf - R InstanceOf 3 +New - +Null - L +Return - +Switch - +This - V +Throw - +True - L +Try - +TypeOf TypeOf +Var - +Void Void +While - +With - diff --git a/Parser.hpp b/Parser.hpp new file mode 100644 index 0000000..65806af --- /dev/null +++ b/Parser.hpp @@ -0,0 +1,2 @@ +class CYParser { +}; diff --git a/Parser.py b/Parser.py new file mode 100755 index 0000000..a8b92d7 --- /dev/null +++ b/Parser.py @@ -0,0 +1,100 @@ +#!/usr/bin/python + +import sys + +lines = sys.stdin.read().rstrip('\n').split('\n') + +def data(line): + name = line[0].replace('&', 'Ampersand').replace('^', 'Carrot').replace('=', 'Equal').replace('!', 'Exclamation').replace('-', 'Hyphen').replace('<', 'Left').replace('%', 'Percent').replace('.', 'Period').replace('|', 'Pipe').replace('+', 'Plus').replace('>', 'Right').replace('/', 'Slash').replace('*', 'Star').replace('~', 'Tilde') + text = line[0].lower() + word = text[0].isalpha() + prefix = None if line[1] == '-' else line[1] + assign = None if len(line) < 3 or line[2] != 'A' else '' if len(line) < 4 else line[3] + infix = None if len(line) < 3 or line[2] != 'R' else line[3] + precedence = line[4] if infix != None and len(line) > 4 else None + postfix = infix if infix != None and precedence == None else None + if postfix != None: + infix = None + return name, text, word, prefix, assign, infix, precedence, postfix + +def express(expression, type, args, call): + print 'struct CYExpression%(expression)s :' % locals() + print ' CYExpression%(type)s' % locals() + print '{' + print ' CYExpression%(expression)s(%(args)s) :' % locals() + print ' CYExpression%(type)s(%(call)s)' % locals() + print ' {' + print ' }' + print '};' + print + +for line in lines: + line = line.split() + name, text, word, prefix, assign, infix, precedence, postfix = data(line) + + print 'struct CYToken%(name)s :' % locals() + if prefix != None: + print ' CYTokenPrefix,' + if infix != None: + print ' CYTokenInfix,' + if postfix != None: + print ' CYTokenPostfix,' + if assign != None: + print ' CYTokenAssignment,' + if word: + print ' CYTokenWord,' + print ' virtual CYToken' + print '{' + print ' virtual const char *Text() const {' + print ' return "%(text)s";' % locals() + print ' }' + if precedence != None or prefix != None or assign != None or infix != None: + print + if precedence != None: + print ' virtual unsigned Precedence() const {' + print ' return %(precedence)s;' % locals() + print ' }' + print + if prefix != None: + print ' virtual CYExpression *PrefixExpression(apr_pool_t *pool, CYExpression *rhs) const;' + if infix != None: + print ' virtual CYExpression *InfixExpression(apr_pool_t *pool, CYExpression *lhs, CYExpression *rhs) const;' + if postfix != None: + print ' virtual CYExpression *PostfixExpression(apr_pool_t *pool, CYExpression *lhs) const;' + if assign != None: + print ' virtual CYExpression *AssignmentExpression(apr_pool_t *pool, CYExpression *lhs, CYExpression *rhs) const;' + print '};' + print + if prefix != None: + express(prefix, 'Prefix', 'CYExpression *rhs', 'rhs') + if infix != None: + express(infix, 'Infix', 'CYExpression *lhs, CYExpression *rhs', 'lhs, rhs') + if postfix != None: + express(postfix, 'Postfix', 'CYExpression *lhs', 'lhs') + if assign != None: + express('Assign' + assign, 'Assignment', 'CYExpression *lhs, CYExpression *rhs', 'lhs, rhs') + +for line in lines: + line = line.split() + name, text, word, prefix, assign, infix, precedence, postfix = data(line) + + if prefix != None: + print 'CYExpression *CYToken%(name)s::PrefixExpression(apr_pool_t *pool, CYExpression *rhs) const {' % locals() + print ' return new(pool) CYExpression%(prefix)s(rhs);' % locals() + print '}' + print + if infix != None: + print 'CYExpression *CYToken%(name)s::InfixExpression(apr_pool_t *pool, CYExpression *lhs, CYExpression *rhs) const {' % locals() + print ' return new(pool) CYExpression%(infix)s(lhs, rhs);' % locals() + print '}' + print + if postfix != None: + print 'CYExpression *CYToken%(name)s::PostfixExpression(apr_pool_t *pool, CYExpression *rhs) const {' % locals() + print ' return new(pool) CYExpression%(postfix)s(rhs);' % locals() + print '}' + print + if assign != None: + print 'CYExpression *CYToken%(name)s::AssignmentExpression(apr_pool_t *pool, CYExpression *lhs, CYExpression *rhs) const {' % locals() + print ' return new(pool) CYExpressionAssign%(assign)s(lhs, rhs);' % locals() + print '}' + print diff --git a/makefile b/makefile index d8c9ae5..b7c8770 100644 --- a/makefile +++ b/makefile @@ -14,7 +14,7 @@ link := -framework CoreFoundation -framework Foundation -F${PKG_ROOT}/System/Lib all: cycript libcycript.dylib libcycript.plist clean: - rm -f libcycript.dylib cycript libcycript.plist Struct.hpp + rm -f libcycript.dylib cycript libcycript.plist Struct.hpp lex.cy.c Cycript.tab.c Cycript.tab.h libcycript.plist: Bridge.def makefile sed -e 's/^C/0/;s/^F/1/;s/^V/2/' Bridge.def | while read -r line; do \ @@ -28,11 +28,20 @@ libcycript.plist: Bridge.def makefile echo "$$2 = ($$1, \"$$3\");"; \ done >$@ +Cycript.tab.c Cycript.tab.h: Cycript.y + bison $< + +lex.cy.c: Cycript.l + flex $< + Struct.hpp: $$($(target)gcc -print-prog-name=cc1obj) -print-objc-runtime-info $@ -libcycript.dylib: Library.mm makefile $(menes)/mobilesubstrate/substrate.h sig/*.[ch]pp Struct.hpp - $(target)g++ -dynamiclib -mthumb -g0 -O2 -Wall -Werror -o $@ $(filter %.cpp,$^) $(filter %.mm,$^) -lobjc -I$(menes)/mobilesubstrate $(link) $(flags) +#Parser.hpp: Parser.py Parser.dat +# ./Parser.py $@ + +libcycript.dylib: Library.mm makefile $(menes)/mobilesubstrate/substrate.h sig/*.[ch]pp Struct.hpp Parser.hpp lex.cy.c Cycript.tab.c Cycript.tab.h + $(target)g++ -dynamiclib -mthumb -g0 -O2 -Wall -Werror -o $@ $(filter %.cpp,$^) $(filter %.c,$^) $(filter %.mm,$^) -lobjc -I$(menes)/mobilesubstrate $(link) $(flags) -DYYDEBUG=1 ldid -S $@ cycript: Application.mm libcycript.dylib -- 2.45.2