Convert the interpreter to kotlin
This commit is contained in:
		
							parent
							
								
									d376c30d7a
								
							
						
					
					
						commit
						eaf80390be
					
				@ -1,7 +1,6 @@
 | 
			
		||||
package function
 | 
			
		||||
 | 
			
		||||
import java.lang.annotation.Retention
 | 
			
		||||
import java.lang.annotation.RetentionPolicy.RUNTIME
 | 
			
		||||
import kotlin.annotation.AnnotationRetention.RUNTIME
 | 
			
		||||
import kotlin.annotation.AnnotationTarget.CLASS
 | 
			
		||||
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 createInterpreter(): LispInterpreter {
 | 
			
		||||
        if (isFileBased)
 | 
			
		||||
            return FileLispInterpreter()
 | 
			
		||||
        else if (isInteractive)
 | 
			
		||||
            return InteractiveLispInterpreter()
 | 
			
		||||
 | 
			
		||||
        return LispInterpreter()
 | 
			
		||||
    private fun createInterpreter() = when {
 | 
			
		||||
        isFileBased   -> FileLispInterpreter()
 | 
			
		||||
        isInteractive -> InteractiveLispInterpreter()
 | 
			
		||||
        else          -> LispInterpreter()
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    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.
 | 
			
		||||
 */
 | 
			
		||||
class LispParser(inputStream: InputStream, fileName: String) {
 | 
			
		||||
class LispParser(inputStream: InputStream, fileName: String) : AbstractIterator<SExpression>() {
 | 
			
		||||
 | 
			
		||||
    private val scanner: LispScanner = LispScanner(inputStream, fileName)
 | 
			
		||||
    private var nextToken: Token? = null
 | 
			
		||||
    private var delayedException: LispException? = null
 | 
			
		||||
    private var isNextTokenStored: Boolean = false
 | 
			
		||||
 | 
			
		||||
    override fun computeNext() = if (isEof()) done() else setNext(nextSExpression())
 | 
			
		||||
 | 
			
		||||
    fun isEof(): Boolean {
 | 
			
		||||
        if (!isNextTokenStored)
 | 
			
		||||
            storeNextToken()
 | 
			
		||||
@ -32,7 +34,7 @@ class LispParser(inputStream: InputStream, fileName: String) {
 | 
			
		||||
 | 
			
		||||
        isNextTokenStored = false
 | 
			
		||||
 | 
			
		||||
        return nextToken!!.parseSExpression({ scanner.nextToken })
 | 
			
		||||
        return nextToken!!.parseSExpression { scanner.nextToken }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    private fun storeNextToken() {
 | 
			
		||||
 | 
			
		||||
@ -1,7 +1,7 @@
 | 
			
		||||
package interpreter
 | 
			
		||||
 | 
			
		||||
import environment.RuntimeEnvironment
 | 
			
		||||
import interpreter.InteractiveLispInterpreter.PROMPT
 | 
			
		||||
import interpreter.InteractiveLispInterpreter.Companion.PROMPT
 | 
			
		||||
import org.junit.After
 | 
			
		||||
import org.junit.Assert.assertEquals
 | 
			
		||||
import org.junit.Assert.assertFalse
 | 
			
		||||
 | 
			
		||||
@ -17,12 +17,10 @@ class LispCommentRemovingInputStreamTest {
 | 
			
		||||
    private fun createLispInputStream(inputString: String) =
 | 
			
		||||
        LispCommentRemovingInputStream(createInputStreamFromString(inputString))
 | 
			
		||||
 | 
			
		||||
    private fun readInputStreamIntoString(inputStream: LispInputStream) = StringBuilder().let {
 | 
			
		||||
    private fun readInputStreamIntoString(inputStream: LispInputStream) = StringBuilder().apply {
 | 
			
		||||
        for (c in inputStream)
 | 
			
		||||
            it.append(c.toChar())
 | 
			
		||||
 | 
			
		||||
        it.toString()
 | 
			
		||||
    }
 | 
			
		||||
            append(c.toChar())
 | 
			
		||||
    }.toString()
 | 
			
		||||
 | 
			
		||||
    @Test
 | 
			
		||||
    fun `no bytes in gives no bytes out`() {
 | 
			
		||||
 | 
			
		||||
		Loading…
	
		Reference in New Issue
	
	Block a user