Ejemplo n.º 1
0
        RNode str_extend(RNode list, int term)
        {
            int brace = -1;
            RNode node;
            int nest;

            int c = nextc();
            switch (c) {
            case '$':
                break;
            case '@':
                break;
            case '{':
                break;
            default:
                tokadd('#');
                pushback(c);
                return list;
            }

            string ss = tok();
            if (list == null) {
                list = new RNDStr(thread, ruby, ss);
            }
            else if (toklen() > 0) {
                RNode.list_append(thread, list, new RNStr(thread, ruby, ss));
            }
            newtok();

            switch (c) {
            case '$':
                tokadd('$');
                c = nextc();
                if (c == -1) return new RNEOF();
                switch (c) {
                case '1':
                case '2':
                case '3':
                case '4':
                case '5':
                case '6':
                case '7':
                case '8':
                case '9':
                    while (Char.IsDigit((char)c)) {
                        tokadd(c);
                        c = nextc();
                    }
                    pushback(c);
                    goto fetch_id;

                case '&':
                case '+':
                case '_':
                case '~':
                case '*':
                case '$':
                case '?':
                case '!':
                case '@':
                case ',':
                case '.':
                case '=':
                case ':':
                case '<':
                case '>':
                case '\\':
                refetch:
                    tokadd(c);
                    goto fetch_id;

                default:
                    if (c == term) {
                        RNode.list_append(thread, list, new RNStr(thread, ruby, "#$"));
                        pushback(c);
                        newtok();
                        return list;
                    }
                    switch (c) {
                    case '\"':
                    case '/':
                    case '\'':
                    case '`':
                        goto refetch;
                    }
                    if (!is_identchar(c)) {
                        parser.yyerror("bad global variable in string");
                        newtok();
                        return list;
                    }
                    break;
                }

                while (is_identchar(c)) {
                    tokadd(c);
                    /*
                    if (ismbchar(c)) {
                        int i, len = mbclen(c)-1;

                        for (i = 0; i < len; i++) {
                            c = nextc();
                            tokadd(c);
                        }
                    }
                    */
                    c = nextc();
                }
                pushback(c);
                break;

            case '@':
                tokadd(c);
                c = nextc();
                if (c == '@') {
                    tokadd(c);
                    c = nextc();
                }
                while (is_identchar(c)) {
                    tokadd(c);
                    /*
                    if (ismbchar(c)) {
                        int i, len = mbclen(c)-1;

                        for (i = 0; i < len; i++) {
                            c = nextc();
                            tokadd(c);
                        }
                    }
                    */
                    c = nextc();
                }
                pushback(c);
                break;

            case '{':
                if (c == '{') brace = '}';
                nest = 0;
                do {
                loop_again:
                    c = nextc();
                    switch (c) {
                    case -1:
                        if (nest > 0) {
                            parser.yyerror("bad substitution in string");
                            newtok();
                            return list;
                        }
                        return new RNEOF();
                    case '}':
                        if (c == brace) {
                            if (nest == 0) break;
                            nest--;
                        }
                        tokadd(c);
                        goto loop_again;
                    case '\\':
                        c = nextc();
                        if (c == -1) return new RNEOF();
                        if (c == term) {
                            tokadd(c);
                        }
                        else {
                            tokadd('\\');
                            tokadd(c);
                        }
                        break;
                    case '{':
                        if (brace != -1) nest++;
                        goto case '`';
                    case '\"':
                    case '/':
                    case '`':
                        if (c == term) {
                            pushback(c);
                            RNode.list_append(thread, list, new RNStr(thread, ruby, "#"));
                            ruby.warn("bad substitution in string");
                            RNode.list_append(thread, list, new RNStr(thread, ruby, tok()));
                            newtok();
                            return list;
                        }
                        goto default;
                    default:
                        tokadd(c);
                        break;
                    }
                } while (c != brace);
                break;
            }

        fetch_id:
            node = new RNEVStr(thread, ruby, tok());
            RNode.list_append(thread, list, node);
            newtok();

            return list;
        }
Ejemplo n.º 2
0
        int here_document(int term, int indent)
        {
            int c;
            string line = String.Empty;
            RNode list = null;
            int linesave = thread.line;

            newtok();
            switch (term) {
            case '\'':
                goto case '`';
            case '"':
                goto case '`';
            case '`':
                while ((c = nextc()) != term) {
                    tokadd(c);
                }
                if (term == '\'') term = '\0';
                break;

            default:
                c = term;
                term = '"';
                if (!is_identchar(c)) {
                    ruby.warn("use of bare << to mean <<\"\" is deprecated");
                    break;
                }
                while (is_identchar(c)) {
                    tokadd(c);
                    c = nextc();
                }
                pushback(c);
                break;
            }
            string lastline_save = lastline;
            int offset_save = pcur - pbeg;
            string eos = string.Copy(tok());
            int len = eos.Length;

            string str = String.Empty;
            for (;;) {
                lastline = line = getline();
                if (line == null) {
                    thread.line = linesave;
                    thread.CompileError("can't find string \"" + eos + "\" anywhere before EOF");
                    return 0;
                }
                thread.line++;
                string p = line;
                if (indent > 0) {
                    while (p.Length > 0 && (p[0] == ' ' || p[0] == '\t')) {
                        p = p.Substring(1);
                    }
                }
                if (String.Compare(eos, 0, p, 0, len) == 0) {
                    if (p[len] == '\n' || p[len] == '\r')
                        break;
                    if (len == line.Length)
                        break;
                }
                pbeg = pcur = 0;
                pend = pcur + line.Length;
            retry:
                switch (parse_string(term, '\n', '\n')) {
                case Token.tSTRING:
                    // fall down to the next case
                case Token.tXSTRING:
                    {
                    yylval = (string)yylval + "\n";
                    }
                    if (list == null) {
                        str += (string)yylval;
                    }
                    else {
                        RNode.list_append(thread, list, new RNStr(thread, ruby, (string)yylval));
                    }
                    break;
                case Token.tDSTRING:
                    if (list == null) list = new RNDStr(thread, ruby, str);
                    goto case Token.tDXSTRING;
                case Token.tDXSTRING:
                    if (list == null) list = new RNDXStr(thread, ruby, str);

                    RNode.list_append(thread, (RNode)yylval, new RNStr(thread, ruby, "\n"));
                    RNStr val = new RNStr((RNStr)yylval);
                    yylval = new RNArray(thread, val);
                    ((RNode)yylval).next = ((RNode)yylval).head.next;
                    RNode.list_concat(list, (RNode)yylval);
                    break;

                case 0:
                    thread.line = linesave;
                    thread.CompileError("can't find string \"" + eos + "\" anywhere before EOF");
                    return 0;
                }
                if (pcur != pend) {
                    goto retry;
                }
            }
            lastline = lastline_save;
            pbeg = 0;
            pend = lastline.Length;
            pcur = offset_save;

            lex_state = EXPR.END;
            heredoc_end = thread.line;
            thread.line = linesave;
            if (list != null) {
                list.SetLine(linesave+1);
                yylval = list;
            }
            switch (term) {
            case '\0':
                goto case '"';
            case '\'':
                goto case '"';
            case '"':
                if (list != null) return Token.tDSTRING;
                yylval = str;
                return Token.tSTRING;
            case '`':
                if (list != null) return Token.tDXSTRING;
                yylval = str;
                return Token.tXSTRING;
            }
            return 0;
        }