Convert the interpreter to kotlin
This commit is contained in:
		
							parent
							
								
									d376c30d7a
								
							
						
					
					
						commit
						eaf80390be
					
				@ -1,7 +1,6 @@
 | 
				
			|||||||
package function
 | 
					package function
 | 
				
			||||||
 | 
					
 | 
				
			||||||
import java.lang.annotation.Retention
 | 
					import kotlin.annotation.AnnotationRetention.RUNTIME
 | 
				
			||||||
import java.lang.annotation.RetentionPolicy.RUNTIME
 | 
					 | 
				
			||||||
import kotlin.annotation.AnnotationTarget.CLASS
 | 
					import kotlin.annotation.AnnotationTarget.CLASS
 | 
				
			||||||
import kotlin.annotation.AnnotationTarget.FILE
 | 
					import kotlin.annotation.AnnotationTarget.FILE
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
				
			|||||||
@ -1,28 +0,0 @@
 | 
				
			|||||||
package interpreter;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
import sexpression.SExpression;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
public class FileLispInterpreter extends LispInterpreter {
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    private SExpression lastSExpression;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    public FileLispInterpreter() {
 | 
					 | 
				
			||||||
        this.lastSExpression = null;
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    @Override
 | 
					 | 
				
			||||||
    protected SExpression evaluateNextSExpression() {
 | 
					 | 
				
			||||||
        return this.lastSExpression = super.evaluateNextSExpression();
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    @Override
 | 
					 | 
				
			||||||
    protected void printSExpression(SExpression sExpression) {}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    @Override
 | 
					 | 
				
			||||||
    protected void applyFinishingTouches() {
 | 
					 | 
				
			||||||
        if (lastSExpression != null)
 | 
					 | 
				
			||||||
            super.printSExpression(lastSExpression);
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        super.applyFinishingTouches();
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
							
								
								
									
										19
									
								
								src/main/kotlin/interpreter/FileLispInterpreter.kt
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										19
									
								
								src/main/kotlin/interpreter/FileLispInterpreter.kt
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,19 @@
 | 
				
			|||||||
 | 
					package interpreter
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					import sexpression.SExpression
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					class FileLispInterpreter : LispInterpreter() {
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    private var lastSExpression: SExpression? = null
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    override fun printSExpression(sExpression: SExpression) {
 | 
				
			||||||
 | 
					        lastSExpression = sExpression
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    override fun applyFinishingTouches() {
 | 
				
			||||||
 | 
					        if (lastSExpression != null)
 | 
				
			||||||
 | 
					            super.printSExpression(lastSExpression!!)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        super.applyFinishingTouches()
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
@ -1,24 +0,0 @@
 | 
				
			|||||||
package interpreter;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
public class InteractiveLispInterpreter extends LispInterpreter {
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    public static final String PROMPT = "~ ";
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    @Override
 | 
					 | 
				
			||||||
    protected void prompt() {
 | 
					 | 
				
			||||||
        environment.getOutput().print(environment.decoratePrompt(PROMPT));
 | 
					 | 
				
			||||||
        environment.getOutput().flush();
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    @Override
 | 
					 | 
				
			||||||
    protected void evaluateAndPrintNextSExpression() {
 | 
					 | 
				
			||||||
        environment.getOutput().println();
 | 
					 | 
				
			||||||
        super.evaluateAndPrintNextSExpression();
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    @Override
 | 
					 | 
				
			||||||
    protected void applyFinishingTouches() {
 | 
					 | 
				
			||||||
        environment.getOutput().println(environment.decoratePrompt(""));
 | 
					 | 
				
			||||||
        environment.getOutput().flush();
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
							
								
								
									
										27
									
								
								src/main/kotlin/interpreter/InteractiveLispInterpreter.kt
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										27
									
								
								src/main/kotlin/interpreter/InteractiveLispInterpreter.kt
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,27 @@
 | 
				
			|||||||
 | 
					package interpreter
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					import environment.RuntimeEnvironment.decoratePrompt
 | 
				
			||||||
 | 
					import environment.RuntimeEnvironment.output
 | 
				
			||||||
 | 
					import sexpression.SExpression
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					class InteractiveLispInterpreter : LispInterpreter() {
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    override fun prompt() = output?.run {
 | 
				
			||||||
 | 
					        print(decoratePrompt(PROMPT))
 | 
				
			||||||
 | 
					        flush()
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    override fun printSExpression(sExpression: SExpression) = output?.run {
 | 
				
			||||||
 | 
					        println()
 | 
				
			||||||
 | 
					        super.printSExpression(sExpression)
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    override fun applyFinishingTouches() = output?.run {
 | 
				
			||||||
 | 
					        println(decoratePrompt(""))
 | 
				
			||||||
 | 
					        flush()
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    companion object {
 | 
				
			||||||
 | 
					        internal const val PROMPT = "~ "
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
@ -1,93 +0,0 @@
 | 
				
			|||||||
package interpreter;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
import environment.RuntimeEnvironment;
 | 
					 | 
				
			||||||
import error.LispException;
 | 
					 | 
				
			||||||
import parser.LispParser;
 | 
					 | 
				
			||||||
import sexpression.SExpression;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
import java.io.InputStream;
 | 
					 | 
				
			||||||
import java.util.List;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
import static function.builtin.EVAL.eval;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
public class LispInterpreter {
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    protected RuntimeEnvironment environment;
 | 
					 | 
				
			||||||
    private LispParser parser;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    public LispInterpreter() {
 | 
					 | 
				
			||||||
        this.environment = RuntimeEnvironment.INSTANCE;
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    public void interpretLanguageFiles(List<LanguageFile> languageFiles) {
 | 
					 | 
				
			||||||
        for (LanguageFile file : languageFiles) {
 | 
					 | 
				
			||||||
            LispParser languageParser = new LispParser(file.getInputStream(), file.getName());
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
            while (!languageParser.isEof())
 | 
					 | 
				
			||||||
                eval(languageParser.nextSExpression());
 | 
					 | 
				
			||||||
        }
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    public void interpret() {
 | 
					 | 
				
			||||||
        createParser();
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        for (prompt(); !parser.isEof(); prompt())
 | 
					 | 
				
			||||||
            evaluateAndPrintNextSExpression();
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        applyFinishingTouches();
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    private void createParser() {
 | 
					 | 
				
			||||||
        parser = new LispParser(environment.getInput(), environment.getInputName());
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    protected void prompt() {}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    protected void evaluateAndPrintNextSExpression() {
 | 
					 | 
				
			||||||
        try {
 | 
					 | 
				
			||||||
            evaluateAndPrintNextSExpressionWithException();
 | 
					 | 
				
			||||||
        } catch (LispException e) {
 | 
					 | 
				
			||||||
            environment.getErrorManager().handle(e);
 | 
					 | 
				
			||||||
        }
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    private void evaluateAndPrintNextSExpressionWithException() {
 | 
					 | 
				
			||||||
        printSExpression(evaluateNextSExpression());
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    protected SExpression evaluateNextSExpression() {
 | 
					 | 
				
			||||||
        SExpression sExpression = parser.nextSExpression();
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        return eval(sExpression);
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    protected void printSExpression(SExpression sExpression) {
 | 
					 | 
				
			||||||
        String result = environment.decorateValueOutput(String.valueOf(sExpression));
 | 
					 | 
				
			||||||
        environment.getOutput().println(result);
 | 
					 | 
				
			||||||
        environment.getOutput().flush();
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    protected void applyFinishingTouches() {
 | 
					 | 
				
			||||||
        environment.getOutput().println();
 | 
					 | 
				
			||||||
        environment.getOutput().flush();
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    public static class LanguageFile {
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        private InputStream inputStream;
 | 
					 | 
				
			||||||
        private String name;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        public LanguageFile(InputStream inputStream, String name) {
 | 
					 | 
				
			||||||
            this.inputStream = inputStream;
 | 
					 | 
				
			||||||
            this.name = "lang:" + name;
 | 
					 | 
				
			||||||
        }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        public InputStream getInputStream() {
 | 
					 | 
				
			||||||
            return inputStream;
 | 
					 | 
				
			||||||
        }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        public String getName() {
 | 
					 | 
				
			||||||
            return name;
 | 
					 | 
				
			||||||
        }
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
							
								
								
									
										56
									
								
								src/main/kotlin/interpreter/LispInterpreter.kt
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										56
									
								
								src/main/kotlin/interpreter/LispInterpreter.kt
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,56 @@
 | 
				
			|||||||
 | 
					package interpreter
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					import environment.RuntimeEnvironment.decorateValueOutput
 | 
				
			||||||
 | 
					import environment.RuntimeEnvironment.errorManager
 | 
				
			||||||
 | 
					import environment.RuntimeEnvironment.input
 | 
				
			||||||
 | 
					import environment.RuntimeEnvironment.inputName
 | 
				
			||||||
 | 
					import environment.RuntimeEnvironment.output
 | 
				
			||||||
 | 
					import error.LispException
 | 
				
			||||||
 | 
					import function.builtin.EVAL.eval
 | 
				
			||||||
 | 
					import parser.LispParser
 | 
				
			||||||
 | 
					import sexpression.SExpression
 | 
				
			||||||
 | 
					import java.io.InputStream
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					open class LispInterpreter {
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    private lateinit var parser: LispParser
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    fun interpretLanguageFiles(languageFiles: List<LanguageFile>) {
 | 
				
			||||||
 | 
					        for (file in languageFiles)
 | 
				
			||||||
 | 
					            LispParser(file.inputStream, file.name).forEach { eval(it) }
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    fun interpret() {
 | 
				
			||||||
 | 
					        parser = LispParser(input!!, inputName!!)
 | 
				
			||||||
 | 
					        prompt()
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        while (!parser.isEof()) {
 | 
				
			||||||
 | 
					            evaluateAndPrintNextSExpression()
 | 
				
			||||||
 | 
					            prompt()
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        applyFinishingTouches()
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    protected open fun prompt(): Unit? = null
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    protected open fun evaluateAndPrintNextSExpression() = try {
 | 
				
			||||||
 | 
					        printSExpression(eval(parser.nextSExpression()))
 | 
				
			||||||
 | 
					    } catch (e: LispException) {
 | 
				
			||||||
 | 
					        errorManager?.run { handle(e) }
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    protected open fun printSExpression(sExpression: SExpression) = output?.run {
 | 
				
			||||||
 | 
					        println(decorateValueOutput(sExpression.toString()))
 | 
				
			||||||
 | 
					        flush()
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    protected open fun applyFinishingTouches() = output?.run {
 | 
				
			||||||
 | 
					        println()
 | 
				
			||||||
 | 
					        flush()
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    class LanguageFile(val inputStream: InputStream, name: String) {
 | 
				
			||||||
 | 
					        val name: String = "lang:$name"
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
@ -151,13 +151,10 @@ object LispInterpreterBuilder {
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
    private fun getInputStream() = if (isFileBased) FileInputStream(inputName) else inputStream
 | 
					    private fun getInputStream() = if (isFileBased) FileInputStream(inputName) else inputStream
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    private fun createInterpreter(): LispInterpreter {
 | 
					    private fun createInterpreter() = when {
 | 
				
			||||||
        if (isFileBased)
 | 
					        isFileBased   -> FileLispInterpreter()
 | 
				
			||||||
            return FileLispInterpreter()
 | 
					        isInteractive -> InteractiveLispInterpreter()
 | 
				
			||||||
        else if (isInteractive)
 | 
					        else          -> LispInterpreter()
 | 
				
			||||||
            return InteractiveLispInterpreter()
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        return LispInterpreter()
 | 
					 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    class LispFileNotFoundException(val e: FileNotFoundException) : CriticalLispException() {
 | 
					    class LispFileNotFoundException(val e: FileNotFoundException) : CriticalLispException() {
 | 
				
			||||||
 | 
				
			|||||||
@ -10,13 +10,15 @@ import java.io.InputStream
 | 
				
			|||||||
/**
 | 
					/**
 | 
				
			||||||
 * Converts a stream of bytes into internal representations of Lisp s-expressions.
 | 
					 * Converts a stream of bytes into internal representations of Lisp s-expressions.
 | 
				
			||||||
 */
 | 
					 */
 | 
				
			||||||
class LispParser(inputStream: InputStream, fileName: String) {
 | 
					class LispParser(inputStream: InputStream, fileName: String) : AbstractIterator<SExpression>() {
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    private val scanner: LispScanner = LispScanner(inputStream, fileName)
 | 
					    private val scanner: LispScanner = LispScanner(inputStream, fileName)
 | 
				
			||||||
    private var nextToken: Token? = null
 | 
					    private var nextToken: Token? = null
 | 
				
			||||||
    private var delayedException: LispException? = null
 | 
					    private var delayedException: LispException? = null
 | 
				
			||||||
    private var isNextTokenStored: Boolean = false
 | 
					    private var isNextTokenStored: Boolean = false
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    override fun computeNext() = if (isEof()) done() else setNext(nextSExpression())
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    fun isEof(): Boolean {
 | 
					    fun isEof(): Boolean {
 | 
				
			||||||
        if (!isNextTokenStored)
 | 
					        if (!isNextTokenStored)
 | 
				
			||||||
            storeNextToken()
 | 
					            storeNextToken()
 | 
				
			||||||
@ -32,7 +34,7 @@ class LispParser(inputStream: InputStream, fileName: String) {
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
        isNextTokenStored = false
 | 
					        isNextTokenStored = false
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        return nextToken!!.parseSExpression({ scanner.nextToken })
 | 
					        return nextToken!!.parseSExpression { scanner.nextToken }
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    private fun storeNextToken() {
 | 
					    private fun storeNextToken() {
 | 
				
			||||||
 | 
				
			|||||||
@ -1,7 +1,7 @@
 | 
				
			|||||||
package interpreter
 | 
					package interpreter
 | 
				
			||||||
 | 
					
 | 
				
			||||||
import environment.RuntimeEnvironment
 | 
					import environment.RuntimeEnvironment
 | 
				
			||||||
import interpreter.InteractiveLispInterpreter.PROMPT
 | 
					import interpreter.InteractiveLispInterpreter.Companion.PROMPT
 | 
				
			||||||
import org.junit.After
 | 
					import org.junit.After
 | 
				
			||||||
import org.junit.Assert.assertEquals
 | 
					import org.junit.Assert.assertEquals
 | 
				
			||||||
import org.junit.Assert.assertFalse
 | 
					import org.junit.Assert.assertFalse
 | 
				
			||||||
 | 
				
			|||||||
@ -17,12 +17,10 @@ class LispCommentRemovingInputStreamTest {
 | 
				
			|||||||
    private fun createLispInputStream(inputString: String) =
 | 
					    private fun createLispInputStream(inputString: String) =
 | 
				
			||||||
        LispCommentRemovingInputStream(createInputStreamFromString(inputString))
 | 
					        LispCommentRemovingInputStream(createInputStreamFromString(inputString))
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    private fun readInputStreamIntoString(inputStream: LispInputStream) = StringBuilder().let {
 | 
					    private fun readInputStreamIntoString(inputStream: LispInputStream) = StringBuilder().apply {
 | 
				
			||||||
        for (c in inputStream)
 | 
					        for (c in inputStream)
 | 
				
			||||||
            it.append(c.toChar())
 | 
					            append(c.toChar())
 | 
				
			||||||
 | 
					    }.toString()
 | 
				
			||||||
        it.toString()
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
    @Test
 | 
					    @Test
 | 
				
			||||||
    fun `no bytes in gives no bytes out`() {
 | 
					    fun `no bytes in gives no bytes out`() {
 | 
				
			||||||
 | 
				
			|||||||
		Loading…
	
		Reference in New Issue
	
	Block a user