fork download
  1. import java.io.BufferedReader;
  2. import java.io.InputStreamReader;
  3. import java.lang.StringBuilder;
  4.  
  5. class Lisp
  6. {
  7. public static final int VERSION_MAJOR = 0;
  8. public static final int VERSION_MINOR = 1;
  9. public static final int VERSION_REVISION = 0;
  10.  
  11. public static String getVersion()
  12. {
  13. return ( VERSION_MAJOR + "." + VERSION_MINOR + "." + VERSION_REVISION );
  14. }
  15.  
  16. public static void main( String[] args ) throws java.lang.Exception
  17. {
  18. Lisp lisp = new Lisp();
  19.  
  20.  
  21. final String PROMPT1 = "LISP>";
  22. final String PROMPT2 = " >";
  23. String prompt = PROMPT1;
  24. String line;
  25.  
  26. System.out.println( "-----------------------------------" );
  27. System.out.println( " LISP INTERPRETER " );
  28. System.out.println( "-----------------------------------" );
  29. System.out.println( " Version " + Lisp.getVersion() );
  30. System.out.println( );
  31. System.out.println( " 'ctrl-z' to exit this interpreter " );
  32. System.out.println( );
  33. System.out.println( "-----------------------------------" );
  34. System.out.println( );
  35.  
  36. for (;;)
  37. {
  38. System.out.print( prompt + lisp.getIndent() );
  39.  
  40. line = in.readLine();
  41. if ( line == null )
  42. {
  43. break;
  44. }
  45.  
  46. line = line.trim();
  47. if ( line.length() == 0 )
  48. {
  49. continue;
  50. }
  51.  
  52. if ( line.charAt( 0 ) == ':' ) // System Command
  53. {
  54. line = line.toLowerCase();
  55. if ( ":quit".equals( line )
  56. || ":exit".equals( line )
  57. || ":bye" .equals( line ) )
  58. {
  59. break;
  60. }
  61. else
  62. {
  63. switch ( line )
  64. {
  65. case ":help":
  66. {
  67. System.out.println( "[Help]" );
  68. System.out.println( " :bye same as ':exit'" );
  69. System.out.println( " :cancel cancel inputting lisp code" );
  70. System.out.println( " :exit exit interpreter" );
  71. System.out.println( " :help show this help text" );
  72. System.out.println( " :quit same as ':exit'" );
  73. System.out.println();
  74. }
  75. break;
  76.  
  77. case ":last":
  78. {
  79. System.out.println( "[Last Code]" );
  80. System.out.println( lisp.getLastCode() );
  81. }
  82. break;
  83.  
  84. case ":cancel":
  85. {
  86. System.out.println( "[Cancel]" );
  87. lisp.cancel();
  88. prompt = PROMPT1;
  89. }
  90. break;
  91.  
  92. default:
  93. {
  94. System.out.println( "Error!! Unknown Command! -> " + line );
  95. }
  96. break;
  97. }
  98. continue;
  99. }
  100. }
  101.  
  102. if ( lisp.input( line ) )
  103. {
  104. String result = lisp.excute();
  105. if ( result != null )
  106. {
  107. System.out.println( result );
  108. }
  109. else
  110. {
  111. System.out.println( "Error!!" );
  112. System.out.println( lisp.getErrorMessage() );
  113. }
  114. prompt = PROMPT1;
  115. }
  116. else
  117. {
  118. prompt = PROMPT2;
  119. }
  120. }
  121.  
  122. }
  123.  
  124. private int bracketcounter = 0;
  125. private StringBuilder lastcode;
  126.  
  127. public Lisp() {
  128. lastcode = new StringBuilder();
  129. }
  130.  
  131. public void cancel()
  132. {
  133. bracketcounter = 0;
  134. }
  135.  
  136. public boolean input( String src )
  137. {
  138. int sp = 0;
  139.  
  140. if ( bracketcounter == 0 )
  141. {
  142. lastcode.delete( 0 , lastcode.length() );
  143. }
  144. else
  145. {
  146. sp = -1;
  147. }
  148.  
  149. int len = src.length();
  150. for ( int i = 0 ; i < len ; i++ )
  151. {
  152. sp++;
  153. char ch = src.charAt( i );
  154. lastcode.append( ch );
  155. switch ( ch )
  156. {
  157. case ' ':
  158. case '\t':
  159. case '\n':
  160. case '\r':
  161. {
  162. if ( sp == 0 )
  163. {
  164. lastcode.delete( lastcode.length() - 1 , lastcode.length() );
  165. }
  166. sp = -1;
  167. }
  168. break;
  169.  
  170. case '(': // Open Bracket
  171. {
  172. bracketcounter++;
  173. sp = -1;
  174. }
  175. break;
  176.  
  177. case ')': // Close Bracket
  178. {
  179. if ( sp == 0 )
  180. {
  181. lastcode.delete( lastcode.length() - 2 , lastcode.length() - 1 );
  182. }
  183. bracketcounter--;
  184. }
  185. break;
  186.  
  187. case ';': // Comment
  188. {
  189. lastcode.delete( lastcode.length() - 1 , lastcode.length() );
  190. i = len;
  191. sp--;
  192. }
  193. break;
  194.  
  195. default: // Symbol (Atom)
  196. {
  197. }
  198. break;
  199. }
  200. }
  201. if ( sp >= 0 && bracketcounter > 0 )
  202. {
  203. lastcode.append( ' ' );
  204. }
  205. return ( bracketcounter == 0 );
  206. }
  207.  
  208. public String excute()
  209. {
  210. return ( null );
  211. }
  212.  
  213. public String getErrorMessage()
  214. {
  215. return ( "" );
  216. }
  217.  
  218. public String getLastCode()
  219. {
  220. return ( lastcode.toString() );
  221. }
  222.  
  223. public String getIndent()
  224. {
  225. final String spacer = " ";
  226. if ( bracketcounter == 0 )
  227. {
  228. return ( "" );
  229. }
  230. else if ( bracketcounter * 2 < spacer.length() )
  231. {
  232. return ( spacer.substring( spacer.length() - bracketcounter * 2 ) );
  233. }
  234. else
  235. {
  236. return ( spacer );
  237. }
  238. }
  239. }
Success #stdin #stdout 0.06s 380224KB
stdin
:help
(hoge
aiueo ;; comment line
fuga)
:last
(foo
bar
:cancel
:last
stdout
-----------------------------------
        LISP   INTERPRETER         
-----------------------------------
 Version 0.1.0

 'ctrl-z' to exit this interpreter 

-----------------------------------

LISP>[Help]
 :bye      same as ':exit'
 :cancel   cancel inputting lisp code
 :exit     exit interpreter
 :help     show this help text
 :quit     same as ':exit'

LISP>    >      >  Error!!

LISP>[Last Code]
(hoge aiueo fuga)
LISP>    >      >  [Cancel]
LISP>[Last Code]
(foo bar 
LISP>