]> git.saurik.com Git - cycript.git/blobdiff - trash/Parser.mm
Moving various files that aren't used anymore from my WC into a trash folder for...
[cycript.git] / trash / Parser.mm
diff --git a/trash/Parser.mm b/trash/Parser.mm
new file mode 100644 (file)
index 0000000..eb441ef
--- /dev/null
@@ -0,0 +1,232 @@
+struct CYExpression {
+};
+
+struct CYToken {
+    virtual const char *Text() const = 0;
+};
+
+struct CYTokenPrefix :
+    virtual CYToken
+{
+};
+
+struct CYTokenInfix :
+    virtual CYToken
+{
+    virtual unsigned Precedence() const = 0;
+};
+
+struct CYTokenPostfix :
+    virtual CYToken
+{
+};
+
+struct CYTokenAssignment :
+    virtual CYToken
+{
+};
+
+struct CYTokenAccess :
+    virtual CYToken
+{
+};
+
+struct CYTokenLiteral :
+    CYExpression,
+    virtual CYToken
+{
+};
+
+struct CYTokenString :
+    CYTokenLiteral
+{
+};
+
+struct CYTokenNumber :
+    CYTokenLiteral
+{
+};
+
+struct CYTokenWord :
+    virtual CYToken
+{
+};
+
+struct CYTokenIdentifier :
+    CYExpression,
+    CYTokenWord
+{
+    const char *word_;
+
+    virtual const char *Text() const {
+        return word_;
+    }
+};
+
+struct CYTokenColon :
+    CYToken
+{
+};
+
+struct CYTokenComma :
+    CYToken
+{
+};
+
+struct CYTokenSemi :
+    CYToken
+{
+};
+
+struct CYTokenQuestion :
+    CYToken
+{
+};
+
+std::set<const char *, CStringMapLess> OperatorWords_;
+
+struct CYParser {
+    FILE *fin_;
+    FILE *fout_;
+
+    size_t capacity_;
+    char *data_;
+
+    size_t offset_;
+    size_t size_;
+
+    CYPool pool_;
+
+    CYParser(FILE *fin, FILE *fout) :
+        fin_(fin),
+        fout_(fout),
+        capacity_(1024),
+        data_(reinterpret_cast<char *>(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<char *>(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_]])
+            ++offset_;
+    }
+
+    CYToken *ParseToken(const char *prompt) {
+        char next;
+
+        do {
+            if (offset_ == size_ && (prompt == NULL || !ReadLine(prompt)))
+                return false;
+            next = data_[offset_++];
+        } while (next == ' ' || next == '\t');
+
+        CYTokenType type;
+        size_t index(offset_ - 1);
+
+        if (WordStartRange_[next]) {
+            ScanRange(WordEndRange_);
+            type = CYTokenWord;
+        } else if (next == '.') {
+            char after(data_[offset_]);
+            if (after >= '0' && after <= '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;
+            }
+
+            type = CYTokenLiteral;
+        } else if (next == '(' || next == '{' || next == '[') {
+            type = CYTokenOpen;
+        } else if (next == ')' || next == '}' || next == ']') {
+            type = CYTokenClose;
+        } else if (next == ';') {
+            type = CYTokenSemiColon;
+        } else {
+            printf(":( %u\n", next);
+            _assert(false);
+        }
+
+        char *value(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(const char *prompt) {
+        CYToken *token(ParseToken(prompt));
+        return token;
+    }
+};