001package com.randomnoun.common.jessop.lang;
002
003/* (c) 2016 randomnoun. All Rights Reserved. This work is licensed under a
004 * BSD Simplified License. ( http://www.randomnoun.com/bsd-simplified.html ) 
005 */
006
007import org.apache.log4j.Logger;
008
009import com.randomnoun.common.jessop.AbstractJessopScriptBuilder;
010import com.randomnoun.common.jessop.JessopScriptBuilder;
011
012public class RubyJessopScriptBuilder extends AbstractJessopScriptBuilder implements JessopScriptBuilder {
013
014        Logger logger = Logger.getLogger(RubyJessopScriptBuilder.class);
015        int outputLine = 1;        // current line number in the target script;
016        int lastScriptletLine = 1; // the last line number of the last scriptlet (used for suppressEol)
017
018        public RubyJessopScriptBuilder() {
019        }
020        private void skipToLine(int line) {
021                while (outputLine < line) { print("\n"); }
022        }
023        private void print(String s) {
024                // logger.info("** PRINT " + s);
025                pw.print(s);
026                for (int i=0; i<s.length(); i++) {
027                        if (s.charAt(i)=='\n') { outputLine++; } 
028                }
029        }
030        private static String escapeLua(String string) {
031                /* valid escapes ( https://en.wikibooks.org/wiki/Ruby_Programming/Syntax/Literals#Strings )
032\a      bell
033\b      back space
034\f      form feed
035\n      newline
036\r      carriage return
037\t      horizontal tab
038\v      vertical tab
039\e      escape
040\\      backslash
041\"      double quote
042                 */
043                
044        StringBuilder sb = new StringBuilder(string.length());
045        String escapeChars = "\u0007" + "\u0008" + "\u000f" + "\n" + "\r" + "\u0009" + "\u000b" + "\u001b" + "\\" + "\"";
046        String backslashChars = "abfnrtve\\\"";
047                for (int i = 0; i<string.length(); i++) {
048                        char ch = string.charAt(i);
049                        int pos = escapeChars.indexOf(ch);
050                        if (pos !=- 1) {
051                           sb.append("\\" + backslashChars.charAt(pos));
052                        } else {
053                                sb.append(ch);
054                        }
055                }
056        return sb.toString();
057    }
058        
059        @Override
060        public void emitText(int line, String s) {
061                if (outputLine == line) { print ("; "); }
062                skipToLine(line);
063                s = suppressEol(s, declarations.isSuppressEol() && lastScriptletLine == line);
064                print("print \"" + escapeLua(s) + "\"");
065                lastScriptletLine = 0; // don't suppress eols on this line
066        }
067        @Override
068        public void emitExpression(int line, String s) {
069                if (outputLine == line) { print ("; "); }
070                skipToLine(line);
071                print("print (" + s + ")");
072                lastScriptletLine = 0; // don't suppress eols on this line
073        }
074        @Override
075        public void emitScriptlet(int line, String s) {
076                if (outputLine == line) { print ("; "); }
077                skipToLine(line);
078                print(s);
079                lastScriptletLine = line;
080                for (int i=0; i<s.length(); i++) { if (s.charAt(i)=='\n') { lastScriptletLine++; } }
081        }
082        @Override
083        public String getLanguage() {
084                return "ruby";
085        }
086        @Override
087        public String getDefaultScriptEngineName() {
088                return "jruby";
089        }
090        @Override
091        public String getDefaultExceptionConverterClassName() {
092                return "com.randomnoun.common.jessop.engine.JRubyExceptionConverter";
093                // return null;
094        }
095
096        
097
098}