Skip to content

Commit 46d3545

Browse files
committed
Add lambda support(passing param as lambda
1 parent 885f1ee commit 46d3545

File tree

6 files changed

+37
-54
lines changed

6 files changed

+37
-54
lines changed

README.md

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,9 @@ This is an interpreter for a dialect of lisp, running on JVM.
1919

2020
## [About the language](https://github.com/lice-lang/lice-reference)
2121

22+
See [FeatureTest](src/test/kotlin/org/lice/FeatureTest.kt) to learn more about the language
23+
feature.
24+
2225
## It looks like:
2326

2427
```lisp
@@ -39,7 +42,7 @@ allprojects {
3942
}
4043
4144
dependencies {
42-
compile 'com.github.lice-lang:lice:v3.0.5'
45+
compile 'com.github.lice-lang:lice:v3.1'
4346
}
4447
```
4548

@@ -48,15 +51,15 @@ But if you use Scala, you can add it to your sbt dependency, by adding the stuff
4851
```sbtshell
4952
resolvers += "jitpack" at "https://jitpack.io"
5053
51-
libraryDependencies += "com.github.lice-lang" % "lice" % "v3.0.5"
54+
libraryDependencies += "com.github.lice-lang" % "lice" % "v3.1"
5255
```
5356

5457
And if you're a Clojure developer, why not try build it with leiningen?
5558

5659
```leiningen
5760
:repositories [["jitpack" "https://jitpack.io"]]
5861
59-
:dependencies [[com.github.lice-lang/lice "v3.0.5"]]
62+
:dependencies [[com.github.lice-lang/lice "v3.1"]]
6063
```
6164

6265
## Contribute

build.gradle

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,8 @@
11
group 'org.lice'
2-
version '3.0.5'
2+
version '3.1'
33

44
buildscript {
5-
ext.kotlin_version = '1.1.1'
5+
ext.kotlin_version = '1.1.2'
66
repositories {
77
mavenCentral()
88
}

src/main/kotlin/org/lice/compiler/model/Ast.kt

Lines changed: 9 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -46,6 +46,8 @@ interface Node {
4646
// fun eval(params: List<Node> = emptyList<Node>()): Node
4747
fun eval(): Value
4848

49+
fun process() = this
50+
4951
val meta: MetaData
5052

5153
override fun toString(): String
@@ -92,6 +94,7 @@ class ExpressionNode(
9294

9395
override fun eval(): Value {
9496
super.beforeEval()
97+
val node = process()
9598
return when (node) {
9699
is SymbolNode -> node.eval(params)
97100
is ExpressionNode -> node.eval(params)
@@ -101,13 +104,19 @@ class ExpressionNode(
101104

102105
fun eval(outer: List<Node>): Value {
103106
super.beforeEval()
107+
val node = process()
104108
return when (node) {
105109
is SymbolNode -> node.eval(params, outer)
106110
is ExpressionNode -> node.eval(params)
107111
else -> node.eval()
108112
}
109113
}
110114

115+
override fun process() = when (node) {
116+
is SymbolNode -> node.function().invoke(meta, params)
117+
else -> node.process()
118+
}
119+
111120
override fun toString() = "function: <$> with ${params.size} params"
112121
}
113122

@@ -130,7 +139,6 @@ class SymbolNode(
130139

131140
fun function() = symbolList.getFunction(name) ?: undefinedVariable(name, meta)
132141

133-
134142
override fun toString() = "symbol: <$name>"
135143
}
136144

@@ -140,7 +148,6 @@ class EmptyNode(override val meta: MetaData) : Node {
140148
return Nullptr
141149
}
142150

143-
// override fun eval(params: List<Node>) = Nullptr
144151
override fun toString() = "null: <null>"
145152
}
146153

src/main/kotlin/org/lice/compiler/util/Extension.kt

Lines changed: 0 additions & 32 deletions
Original file line numberDiff line numberDiff line change
@@ -11,43 +11,11 @@ package org.lice.compiler.util
1111

1212
import org.lice.lang.Echoer
1313

14-
var DEBUGGING = true
15-
16-
var VERBOSE = true
17-
1814
fun <T> T.println(): T {
1915
Echoer.echoln(this)
2016
return this
2117
}
2218

23-
fun <T> T.debugOutput(): T {
24-
if (DEBUGGING) Echoer.echoln(this)
25-
return this
26-
}
27-
28-
inline fun <T> T.debugApply(block: T.() -> Unit): T {
29-
if (DEBUGGING) this.block()
30-
return this
31-
}
32-
33-
inline fun debug(block: () -> Unit) {
34-
if (DEBUGGING) block()
35-
}
36-
37-
inline fun verbose(block: () -> Unit) {
38-
if (VERBOSE) block()
39-
}
40-
41-
fun <T> T.verboseOutput(): T {
42-
if (VERBOSE) Echoer.echoln(this)
43-
return this
44-
}
45-
46-
inline fun <T> T.verboseApply(block: T.() -> Unit): T {
47-
if (VERBOSE) this.block()
48-
return this
49-
}
50-
5119
inline fun forceRun(block: () -> Unit) {
5220
try {
5321
block()

src/main/kotlin/org/lice/repl/Repl.kt

Lines changed: 3 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -2,8 +2,6 @@ package org.lice.repl
22

33
import org.lice.compiler.parse.buildNode
44
import org.lice.compiler.parse.mapAst
5-
import org.lice.compiler.util.DEBUGGING
6-
import org.lice.compiler.util.VERBOSE
75
import org.lice.compiler.util.println
86
import org.lice.core.SymbolList
97
import org.lice.lang.Echoer
@@ -18,33 +16,29 @@ import org.lice.lang.Echoer
1816
class Repl
1917
@JvmOverloads
2018
constructor(val symbolList: SymbolList = SymbolList(true)) {
21-
var stackTrace: Throwable? = null
2219

2320
init {
2421
"""Lice language repl $VERSION_CODE
2522
|see: https://github.com/lice-lang/lice
2623
27-
|剑未佩妥,出门已是江湖。千帆过尽,归来仍是少年。
28-
|Stay young stay simple, and make yourself naive."""
24+
|剑未佩妥,出门已是江湖。千帆过尽,归来仍是少年。"""
2925
.trimMargin()
3026
.println()
3127
Echoer.echo(HINT)
32-
DEBUGGING = false
33-
VERBOSE = false
3428
}
3529

3630
fun handle(str: String): Boolean {
3731
try {
3832
mapAst(buildNode(str), symbolList).eval()
3933
} catch(e: Throwable) {
40-
stackTrace = e
34+
// stackTrace = e
4135
Echoer.echolnErr(e.message ?: "")
4236
}
4337
print(HINT)
4438
return true
4539
}
4640

4741
companion object HintHolder {
48-
val HINT = "Lice > "
42+
val HINT = "|> "
4943
}
5044
}

src/test/kotlin/org/lice/FeatureTest.kt

Lines changed: 17 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -383,20 +383,16 @@ ice1k
383383
}
384384

385385
/**
386-
* mention:
387-
* () means evaluation
388-
* so if you nest expressions, it will be evaluated without passing the params.
389-
*
390386
* I'll show you the procedure:
391387
*
392388
* (((if true + -)) 11 11)
393389
* ((+) 11 11)
394-
* (0 11 11)
390+
* (+ 11 11)
395391
* 0
396392
*/
397393
@Test(timeout = 1000)
398394
fun test27() {
399-
assertEquals(0, Lice.run("(((if true + -)) 11 11)"))
395+
assertEquals(22, Lice.run("(((if true + -)) 11 11)"))
400396
assertEquals(0, Lice.run("+"))
401397
assertEquals(0, Lice.run("-"))
402398
assertEquals(1, Lice.run("*"))
@@ -478,4 +474,19 @@ side-effect
478474
(fuck +)
479475
"""))
480476
}
477+
478+
/**
479+
* expr will keep the parameter everywhere
480+
* lazy will eval params when first invoked
481+
* lambda will eval params before invoked
482+
*
483+
* conclusion: if you want to pass 'function'
484+
* as parameter, please use 'expr'.
485+
*/
486+
@Test(timeout = 1000)
487+
fun test32() {
488+
assertEquals(3, Lice.run("((expr op (op 1 2)) +)"))
489+
assertEquals(0, Lice.run("((lazy op (op 1 2)) +)"))
490+
assertEquals(0, Lice.run("((lambda op (op 1 2)) +)"))
491+
}
481492
}

0 commit comments

Comments
 (0)