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}