From e7ed5354ae029d47ace1bc152aa5686f495e5737 Mon Sep 17 00:00:00 2001 From: "Jay Freeman (saurik)" Date: Thu, 1 Oct 2009 08:19:42 +0000 Subject: [PATCH] More interactivity and @selector start. --- Application.mm | 4 ++++ Cycript.l | 15 +++++++++++++++ Cycript.y | 21 +++++++++++++++++++++ Library.mm | 29 ++++++++++++++++++++++++++--- Output.cpp | 6 ++++++ Parser.hpp | 25 ++++++++++++++++++++++++- makefile | 4 ++-- 7 files changed, 98 insertions(+), 6 deletions(-) diff --git a/Application.mm b/Application.mm index cb12f32..cf84570 100644 --- a/Application.mm +++ b/Application.mm @@ -3,6 +3,10 @@ int CYConsole(FILE *in, FILE *out, FILE *err); +@ /**/protocol a +- (void) a:(int)m; +@end + int main() { return CYConsole(stdin, stdout, stderr); } diff --git a/Cycript.l b/Cycript.l index 6e2a780..eb0c692 100644 --- a/Cycript.l +++ b/Cycript.l @@ -9,6 +9,19 @@ typedef cy::parser::token tk; #define C T yyextra->state_ = CYClear; #define R T yyextra->state_ = CYRestricted; #define N if (yyextra->state_ != CYNewLine) { bool restricted(yyextra->state_ == CYRestricted); if (restricted) { yyextra->state_ = CYClear; return tk::NewLine; } else yyextra->state_ = CYNewLine; } + +#define YY_INPUT(data, value, size) { \ + if (yyextra->size_ == 0) \ + value = YY_NULL; \ + else { \ + size_t copy(std::min(size, yyextra->size_)); \ + memcpy(data, yyextra->data_, copy); \ + yyextra->data_ += copy; \ + yyextra->size_ -= copy; \ + value = copy; \ + } \ +} + %} %option prefix="cy" @@ -82,6 +95,8 @@ Escape \\['"\\bfnrtv]|\\0|\\x[0-9a-fA-F]{2}|\\u[0-9a-fA-F]{4} "[" C return tk::OpenBracket; "]" C return tk::CloseBracket; +"@selector" C return tk::AtSelector; + "break" R yylval->word_ = new CYWord("break"); return tk::Break; "case" C yylval->word_ = new CYWord("case"); return tk::Case; "catch" C yylval->word_ = new CYWord("catch"); return tk::Catch; diff --git a/Cycript.y b/Cycript.y index 8d5c257..b7e17eb 100644 --- a/Cycript.y +++ b/Cycript.y @@ -29,6 +29,7 @@ typedef struct { CYNumber *number_; CYParameter *parameter_; CYProperty *property_; + CYSelector *selector_; CYSource *source_; CYStatement *statement_; CYString *string_; @@ -118,6 +119,8 @@ int cylex(YYSTYPE *lvalp, cy::location *llocp, void *scanner); %token OpenBracket "[" %token CloseBracket "]" +%token AtSelector "@selector" + %token Break "break" %token Case "case" %token Catch "catch" @@ -253,6 +256,9 @@ int cylex(YYSTYPE *lvalp, cy::location *llocp, void *scanner); %type RelationalExpressionNoBF %type RelationalExpressionNoIn %type ReturnStatement +%type SelectorExpression +%type SelectorExpression_ +%type SelectorExpressionOpt %type ShiftExpression %type ShiftExpressionNoBF %type SourceElement @@ -1063,8 +1069,23 @@ MessageExpression : "[" AssignmentExpression SelectorList "]" { $$ = new(driver.pool_) CYMessage($2, $3); } ; +SelectorExpressionOpt + : SelectorExpression_ { $$ = $1; } + | { $$ = NULL; } + ; + +SelectorExpression_ + : WordOpt ":" SelectorExpressionOpt { $$ = new CYSelector($1, true, $3); } + ; + +SelectorExpression + : SelectorExpression_ { $$ = $1; } + | Word { $$ = new CYSelector($1, false, NULL); } + ; + PrimaryExpression_ : MessageExpression { $$ = $1; } + | "@selector" "(" SelectorExpression ")" { $$ = $3; } ; /* }}} */ diff --git a/Library.mm b/Library.mm index 5a5fdf8..1187375 100644 --- a/Library.mm +++ b/Library.mm @@ -919,6 +919,8 @@ static JSStaticValue Pointer_staticValues[2] = { CYDriver::CYDriver(const std::string &filename) : state_(CYClear), + data_(NULL), + size_(0), filename_(filename), source_(NULL) { @@ -930,9 +932,11 @@ CYDriver::~CYDriver() { } void CYDriver::Clear() { + pool_.Clear(); state_ = CYClear; + data_ = NULL; + size_ = 0; source_.clear(); - pool_.Clear(); } void cy::parser::error(const cy::parser::location_type &loc, const std::string &msg) { @@ -940,14 +944,33 @@ void cy::parser::error(const cy::parser::location_type &loc, const std::string & } void CYConsole(FILE *fin, FILE *fout, FILE *ferr) { + std::string line; + + __gnu_cxx::stdio_filebuf bin(fin, std::ios::in); + std::istream sin(&bin); + CYDriver driver(""); while (!feof(fin)) { _pooled driver.Clear(); + fputs("cy# ", fout); + fflush(fout); + cy::parser parser(driver); - if (parser.parse() != 0) - continue; + std::string command; + + for (;;) { + if (!std::getline(sin, line)) + return; + command += line; + driver.data_ = command.c_str(); + driver.size_ = command.size(); + if (parser.parse() == 0) + break; + fputs("cy> ", fout); + fflush(fout); + } for (std::vector::const_iterator i(driver.source_.begin()); i != driver.source_.end(); ++i) { CYSource *source(*i); diff --git a/Output.cpp b/Output.cpp index 9b03d28..4e4040a 100644 --- a/Output.cpp +++ b/Output.cpp @@ -287,6 +287,12 @@ void CYReturn::Output(std::ostream &out) const { out << ';'; } +void CYSelector::Output(std::ostream &out) const { + out << '"'; + out << ""; + out << '"'; +} + void CYSource::Show(std::ostream &out) const { for (const CYSource *next(this); next != NULL; next = next->next_) next->Output(out); diff --git a/Parser.hpp b/Parser.hpp index 7673ad0..346fb93 100644 --- a/Parser.hpp +++ b/Parser.hpp @@ -108,10 +108,16 @@ enum CYState { class CYDriver { public: CYPool pool_; + CYState state_; + void *scanner_; + + const char *data_; + size_t size_; + std::string filename_; + std::vector source_; - void *scanner_; private: void ScannerInit(); @@ -154,6 +160,23 @@ struct CYLiteral : { }; +struct CYSelector : + CYLiteral +{ + CYWord *name_; + bool value_; + CYSelector *after_; + + CYSelector(CYWord *name, bool value, CYSelector *after) : + name_(name), + value_(value), + after_(after) + { + } + + virtual void Output(std::ostream &out) const; +}; + struct CYString : CYLiteral, CYName diff --git a/makefile b/makefile index a42a788..d8533de 100644 --- a/makefile +++ b/makefile @@ -6,7 +6,7 @@ endif package: -flags := -mthumb -g0 -O3 -Wall -Werror -I. +flags := -mthumb -g3 -O0 -Wall -Werror -I. all: cycript libcycript.dylib libcycript.plist @@ -26,7 +26,7 @@ libcycript.plist: Bridge.def done >$@ Cycript.tab.cc Cycript.tab.hh location.hh position.hh: Cycript.y - bison --report=state $< + bison -v --report=state $< lex.cy.c: Cycript.l flex $< -- 2.47.2