summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--checker/build.gradle.kts30
-rw-r--r--checker/src/main/java/lv/enes/orang/checker/Checker.java146
-rw-r--r--checker/src/main/java/lv/enes/orang/checker/CheckerException.java9
-rw-r--r--checker/src/main/java/module-info.java9
-rw-r--r--core/src/main/java/lv/enes/orang/core/ImmutableScope.java47
-rw-r--r--core/src/main/java/lv/enes/orang/core/MutableScope.java26
-rw-r--r--core/src/main/java/lv/enes/orang/core/OrangRuntimeException.java (renamed from orang/src/main/java/lv/enes/orang/OrangRuntimeException.java)4
-rw-r--r--core/src/main/java/lv/enes/orang/core/Scope.java (renamed from orang/src/main/java/lv/enes/orang/Scope.java)23
-rw-r--r--orang/build.gradle.kts1
-rw-r--r--orang/src/main/java/lv/enes/orang/Builtins.java1
-rw-r--r--orang/src/main/java/lv/enes/orang/Evaluator.java9
-rw-r--r--orang/src/main/java/lv/enes/orang/ImmutableScope.java45
-rw-r--r--orang/src/main/java/lv/enes/orang/Main.java11
-rw-r--r--orang/src/main/java/lv/enes/orang/MutableScope.java24
-rw-r--r--orang/src/main/java/lv/enes/orang/value/Array.java2
-rw-r--r--orang/src/main/java/lv/enes/orang/value/BuiltinFunction.java2
-rw-r--r--orang/src/main/java/lv/enes/orang/value/Function.java5
-rw-r--r--orang/src/main/java/lv/enes/orang/value/OrangBoolean.java2
-rw-r--r--orang/src/main/java/lv/enes/orang/value/OrangInteger.java2
-rw-r--r--orang/src/main/java/lv/enes/orang/value/OrangString.java2
-rw-r--r--orang/src/main/java/lv/enes/orang/value/PartialBuiltinFunction.java2
-rw-r--r--orang/src/main/java/lv/enes/orang/value/PartialFunction.java7
-rw-r--r--orang/src/main/java/lv/enes/orang/value/Value.java2
-rw-r--r--orang/src/main/java/module-info.java1
-rw-r--r--settings.gradle.kts2
25 files changed, 311 insertions, 103 deletions
diff --git a/checker/build.gradle.kts b/checker/build.gradle.kts
new file mode 100644
index 0000000..08e9b33
--- /dev/null
+++ b/checker/build.gradle.kts
@@ -0,0 +1,30 @@
1plugins {
2 java
3 id("io.freefair.lombok") version "8.6"
4}
5
6val slf4jVersion = "2.0.13"
7
8repositories {
9 mavenCentral()
10}
11
12dependencies {
13 implementation("org.slf4j:slf4j-api:$slf4jVersion")
14
15 implementation(project(":ast"))
16 implementation(project(":core"))
17 implementation(project(":utils"))
18}
19
20java {
21 sourceCompatibility = JavaVersion.VERSION_22
22 targetCompatibility = JavaVersion.VERSION_22
23 toolchain {
24 languageVersion = JavaLanguageVersion.of(22)
25 }
26}
27
28tasks.withType<JavaCompile> {
29 options.compilerArgs.add("--enable-preview")
30} \ No newline at end of file
diff --git a/checker/src/main/java/lv/enes/orang/checker/Checker.java b/checker/src/main/java/lv/enes/orang/checker/Checker.java
new file mode 100644
index 0000000..446d3f1
--- /dev/null
+++ b/checker/src/main/java/lv/enes/orang/checker/Checker.java
@@ -0,0 +1,146 @@
1package lv.enes.orang.checker;
2
3import lv.enes.orang.ast.*;
4import lv.enes.orang.core.ImmutableScope;
5import lv.enes.orang.core.Scope;
6
7import java.util.HashMap;
8import java.util.Map;
9
10public class Checker implements ExpressionVisitor<Void, CheckerException>, StatementVisitor<Checker, CheckerException> {
11 private final Scope<Boolean> definitions;
12
13 public static <E> Checker of(Map<String, E> builtins) {
14 var boolMap = builtins.keySet()
15 .stream()
16 .<Map<String, Boolean>>collect(
17 HashMap::new,
18 (map, elem) -> map.put(elem, true),
19 Map::putAll
20 );
21 return new Checker(ImmutableScope.of(boolMap));
22 }
23
24 private Checker(Scope<Boolean> definitions) {
25 this.definitions = definitions;
26 }
27
28 @Override
29 public Void visitArray(ArrayExpression array) throws CheckerException {
30 for (var expr : array.items()) {
31 visit(expr);
32 }
33 return null;
34 }
35
36 @Override
37 public Void visitBoolean(BooleanLiteral expr) {
38 // Always ok
39 return null;
40 }
41
42 @Override
43 public Void visitBinaryExpression(BinaryExpression expr) throws CheckerException {
44 visit(expr.lhs());
45 visit(expr.rhs());
46 return null;
47 }
48
49 @Override
50 public Void visitCallExpression(CallExpression expr) throws CheckerException {
51 visit(expr.callee());
52 visit(expr.arg());
53 return null;
54 }
55
56 @Override
57 public Checker visitDefinition(Definition def) throws CheckerException {
58 if (definitions.hasDefinition(def.name())) {
59 throw new CheckerException(STR."Top-level definition '\{def.name()}' redefined!");
60 }
61 return new Checker(ImmutableScope.of(definitions, def.name(), true));
62 }
63
64 @Override
65 public Void visitDoExpression(DoExpression expr) throws CheckerException {
66 for (var child : expr.body()) {
67 visit(child);
68 }
69 return null;
70 }
71
72 @Override
73 public Checker visitExpression(ExpressionStatement expr) throws CheckerException {
74 visit(expr.expr());
75 return this;
76 }
77
78 @Override
79 public Void visitFnExpression(FnExpression expr) throws CheckerException {
80 var args = new HashMap<String, Boolean>();
81 for (var arg : expr.args()) {
82 args.put(arg.name, true);
83 }
84 new Checker(ImmutableScope.of(definitions, args)).visit(expr.body());
85 return null;
86 }
87
88 @Override
89 public Void visitIfElseExpression(IfElseExpression expr) throws CheckerException {
90 visit(expr.condition());
91 visit(expr.trueBranch());
92 visit(expr.falseBranch());
93 return null;
94 }
95
96 @Override
97 public Void visitIntLiteral(IntLiteral expr) {
98 // Always ok
99 return null;
100 }
101
102 @Override
103 public Void visitLetInExpression(LetInExpression expr) throws CheckerException {
104 var locals = new HashMap<String, Boolean>();
105 for (var local : expr.bindings()) {
106 locals.put(local.name(), true);
107 }
108 new Checker(ImmutableScope.of(definitions, locals)).visit(expr.body());
109 return null;
110 }
111
112 @Override
113 public Checker visitProgram(Program program) throws CheckerException {
114 var checker = this;
115 for (var stmt : program.statements()) {
116 checker = checker.visit(stmt);
117 }
118 return checker;
119 }
120
121 @Override
122 public Void visitStringLiteral(StringLiteral expr) {
123 // Always ok
124 return null;
125 }
126
127 @Override
128 public Void visitUnaryExpression(UnaryExpression expr) throws CheckerException {
129 visit(expr.child());
130 return null;
131 }
132
133 @Override
134 public Void visitVariable(VariableExpression expr) throws CheckerException {
135 if (!definitions.hasDefinition(expr.name())) {
136 throw new CheckerException(STR."Variable named '\{expr.name()}' not defined!");
137 }
138 return null;
139 }
140
141 @Override
142 public Void visitVoidExpression() {
143 // Always ok
144 return null;
145 }
146}
diff --git a/checker/src/main/java/lv/enes/orang/checker/CheckerException.java b/checker/src/main/java/lv/enes/orang/checker/CheckerException.java
new file mode 100644
index 0000000..9354f27
--- /dev/null
+++ b/checker/src/main/java/lv/enes/orang/checker/CheckerException.java
@@ -0,0 +1,9 @@
1package lv.enes.orang.checker;
2
3import lv.enes.orang.core.OrangException;
4
5public class CheckerException extends OrangException {
6 public CheckerException(String message) {
7 super(message);
8 }
9}
diff --git a/checker/src/main/java/module-info.java b/checker/src/main/java/module-info.java
new file mode 100644
index 0000000..6e5fa47
--- /dev/null
+++ b/checker/src/main/java/module-info.java
@@ -0,0 +1,9 @@
1module lv.enes.orang.checker {
2 exports lv.enes.orang.checker;
3
4 requires lv.enes.orang.ast;
5 requires lv.enes.orang.core;
6 requires lv.enes.orang.utils;
7
8 requires static lombok;
9} \ No newline at end of file
diff --git a/core/src/main/java/lv/enes/orang/core/ImmutableScope.java b/core/src/main/java/lv/enes/orang/core/ImmutableScope.java
new file mode 100644
index 0000000..5120b08
--- /dev/null
+++ b/core/src/main/java/lv/enes/orang/core/ImmutableScope.java
@@ -0,0 +1,47 @@
1package lv.enes.orang.core;
2
3import java.util.HashMap;
4import java.util.Map;
5
6public class ImmutableScope<E> extends Scope<E> {
7 public static <E> ImmutableScope<E> of(Map<String, E> builtins) {
8 return new ImmutableScope<>(null, new HashMap<>(builtins));
9 }
10
11 public static <E> ImmutableScope<E> of(Scope<E> parent) {
12 if (parent instanceof ImmutableScope<E> imm) {
13 return imm;
14 }
15 return ImmutableScope.of(parent, Map.of());
16 }
17
18 public static <E> ImmutableScope<E> of(Scope<E> parent, String key, E value) {
19 return ImmutableScope.of(parent, Map.of(key, value));
20 }
21
22 public static <E> ImmutableScope<E> of(Scope<E> parent, Map<String, E> definitions) {
23 return new ImmutableScope<>(parent, definitions).maybeFlattened();
24 }
25
26 protected ImmutableScope(Scope<E> parent, Map<String, E> definitions) {
27 super(parent, Map.copyOf(definitions));
28 }
29
30 public ImmutableScope<E> maybeFlattened() {
31 if (depth > MAX_DEPTH) {
32 return flattened();
33 }
34 return this;
35 }
36
37 private ImmutableScope<E> flattened() {
38 if (parent instanceof ImmutableScope<E> immParent) {
39 var flatParent = immParent.flattened();
40 var newDefs = new HashMap<>(flatParent.definitions);
41 newDefs.putAll(definitions);
42 return new ImmutableScope<>(flatParent.parent, newDefs);
43 }
44
45 return this;
46 }
47}
diff --git a/core/src/main/java/lv/enes/orang/core/MutableScope.java b/core/src/main/java/lv/enes/orang/core/MutableScope.java
new file mode 100644
index 0000000..8d8b455
--- /dev/null
+++ b/core/src/main/java/lv/enes/orang/core/MutableScope.java
@@ -0,0 +1,26 @@
1package lv.enes.orang.core;
2
3import java.util.HashMap;
4import java.util.Map;
5
6public class MutableScope<E> extends Scope<E> {
7 public static <E> MutableScope<E> of(Map<String, E> builtins) {
8 return new MutableScope<>(null, new HashMap<>(builtins));
9 }
10
11 public static <E> MutableScope<E> of(Scope<E> parent) {
12 return new MutableScope<>(parent, Map.of());
13 }
14
15 public static <E> MutableScope<E> of(Scope<E> parent, String name, E value) {
16 return new MutableScope<>(parent, Map.of(name, value));
17 }
18
19 protected MutableScope(Scope<E> parent, Map<String, E> definitions) {
20 super(parent, new HashMap<>(definitions));
21 }
22
23 public void setDefinition(String key, E value) {
24 definitions.put(key, value);
25 }
26}
diff --git a/orang/src/main/java/lv/enes/orang/OrangRuntimeException.java b/core/src/main/java/lv/enes/orang/core/OrangRuntimeException.java
index 8a7d575..6ce5f70 100644
--- a/orang/src/main/java/lv/enes/orang/OrangRuntimeException.java
+++ b/core/src/main/java/lv/enes/orang/core/OrangRuntimeException.java
@@ -1,6 +1,4 @@
1package lv.enes.orang; 1package lv.enes.orang.core;
2
3import lv.enes.orang.core.OrangException;
4 2
5public class OrangRuntimeException extends OrangException { 3public class OrangRuntimeException extends OrangException {
6 public OrangRuntimeException(String message) { 4 public OrangRuntimeException(String message) {
diff --git a/orang/src/main/java/lv/enes/orang/Scope.java b/core/src/main/java/lv/enes/orang/core/Scope.java
index 7fe57c7..0f4d23a 100644
--- a/orang/src/main/java/lv/enes/orang/Scope.java
+++ b/core/src/main/java/lv/enes/orang/core/Scope.java
@@ -1,28 +1,21 @@
1package lv.enes.orang; 1package lv.enes.orang.core;
2 2
3import lv.enes.orang.value.Value;
4
5import java.util.HashMap;
6import java.util.Map; 3import java.util.Map;
7 4
8public abstract class Scope { 5public abstract class Scope<E> {
9 public static final int MAX_DEPTH = 4; 6 public static final int MAX_DEPTH = 4;
10 7
11 protected final Scope parent; 8 protected final Scope<E> parent;
12 protected final Map<String, Value> definitions; 9 protected final Map<String, E> definitions;
13 protected final int depth; 10 protected final int depth;
14 11
15 public static MutableScope topLevel() { 12 protected Scope(Scope<E> parent, Map<String, E> definitions) {
16 return new MutableScope(null, new HashMap<>(Builtins.BUILTINS));
17 }
18
19 protected Scope(Scope parent, Map<String, Value> definitions) {
20 this.parent = parent; 13 this.parent = parent;
21 this.definitions = definitions; 14 this.definitions = definitions;
22 this.depth = parent == null ? 0 : parent.depth + 1; 15 this.depth = parent == null ? 0 : parent.depth + 1;
23 } 16 }
24 17
25 public Value getDefinition(String name) throws OrangRuntimeException { 18 public E getDefinition(String name) throws OrangRuntimeException {
26 if (definitions.containsKey(name)) { 19 if (definitions.containsKey(name)) {
27 return definitions.get(name); 20 return definitions.get(name);
28 } else if (parent != null) { 21 } else if (parent != null) {
@@ -31,4 +24,8 @@ public abstract class Scope {
31 throw new OrangRuntimeException(STR."Value named \{name} is not defined!"); 24 throw new OrangRuntimeException(STR."Value named \{name} is not defined!");
32 } 25 }
33 } 26 }
27
28 public boolean hasDefinition(String name) {
29 return definitions.containsKey(name) || parent != null && parent.hasDefinition(name);
30 }
34} 31}
diff --git a/orang/build.gradle.kts b/orang/build.gradle.kts
index ef78ded..ea8fbe0 100644
--- a/orang/build.gradle.kts
+++ b/orang/build.gradle.kts
@@ -23,6 +23,7 @@ dependencies {
23 implementation("org.slf4j:slf4j-simple:$slf4jVersion") 23 implementation("org.slf4j:slf4j-simple:$slf4jVersion")
24 24
25 implementation(project(":ast")) 25 implementation(project(":ast"))
26 implementation(project(":checker"))
26 implementation(project(":core")) 27 implementation(project(":core"))
27 implementation(project(":parser")) 28 implementation(project(":parser"))
28 implementation(project(":utils")) 29 implementation(project(":utils"))
diff --git a/orang/src/main/java/lv/enes/orang/Builtins.java b/orang/src/main/java/lv/enes/orang/Builtins.java
index de296ac..a83f4c5 100644
--- a/orang/src/main/java/lv/enes/orang/Builtins.java
+++ b/orang/src/main/java/lv/enes/orang/Builtins.java
@@ -1,6 +1,7 @@
1package lv.enes.orang; 1package lv.enes.orang;
2 2
3import lombok.extern.slf4j.Slf4j; 3import lombok.extern.slf4j.Slf4j;
4import lv.enes.orang.core.OrangRuntimeException;
4import lv.enes.orang.value.*; 5import lv.enes.orang.value.*;
5 6
6import java.io.IOException; 7import java.io.IOException;
diff --git a/orang/src/main/java/lv/enes/orang/Evaluator.java b/orang/src/main/java/lv/enes/orang/Evaluator.java
index 5d09508..8930f5c 100644
--- a/orang/src/main/java/lv/enes/orang/Evaluator.java
+++ b/orang/src/main/java/lv/enes/orang/Evaluator.java
@@ -1,17 +1,20 @@
1package lv.enes.orang; 1package lv.enes.orang;
2 2
3import lv.enes.orang.ast.*; 3import lv.enes.orang.ast.*;
4import lv.enes.orang.core.MutableScope;
5import lv.enes.orang.core.OrangRuntimeException;
6import lv.enes.orang.core.Scope;
4import lv.enes.orang.value.*; 7import lv.enes.orang.value.*;
5 8
6import java.util.ArrayList; 9import java.util.ArrayList;
7import java.util.Collections; 10import java.util.Collections;
8 11
9public record Evaluator(Scope scope, Value lastResult) implements ExpressionVisitor<Value, OrangRuntimeException>, StatementVisitor<Evaluator, OrangRuntimeException> { 12public record Evaluator(Scope<Value> scope, Value lastResult) implements ExpressionVisitor<Value, OrangRuntimeException>, StatementVisitor<Evaluator, OrangRuntimeException> {
10 public Evaluator() { 13 public Evaluator() {
11 this(Scope.topLevel()); 14 this(MutableScope.of(Builtins.BUILTINS));
12 } 15 }
13 16
14 public Evaluator(Scope scope) { 17 public Evaluator(Scope<Value> scope) {
15 this(scope, Undefined.INSTANCE); 18 this(scope, Undefined.INSTANCE);
16 } 19 }
17 20
diff --git a/orang/src/main/java/lv/enes/orang/ImmutableScope.java b/orang/src/main/java/lv/enes/orang/ImmutableScope.java
deleted file mode 100644
index 9cb6138..0000000
--- a/orang/src/main/java/lv/enes/orang/ImmutableScope.java
+++ /dev/null
@@ -1,45 +0,0 @@
1package lv.enes.orang;
2
3import lv.enes.orang.value.Value;
4
5import java.util.HashMap;
6import java.util.Map;
7
8public class ImmutableScope extends Scope {
9 public static ImmutableScope of(Scope parent) {
10 if (parent instanceof ImmutableScope imm) {
11 return imm;
12 }
13 return ImmutableScope.of(parent, Map.of());
14 }
15
16 public static ImmutableScope of(Scope parent, String key, Value value) {
17 return ImmutableScope.of(parent, Map.of(key, value));
18 }
19
20 public static ImmutableScope of(Scope parent, Map<String, Value> definitions) {
21 return new ImmutableScope(parent, definitions).maybeFlattened();
22 }
23
24 protected ImmutableScope(Scope parent, Map<String, Value> definitions) {
25 super(parent, Map.copyOf(definitions));
26 }
27
28 public ImmutableScope maybeFlattened() {
29 if (depth > MAX_DEPTH) {
30 return flattened();
31 }
32 return this;
33 }
34
35 private ImmutableScope flattened() {
36 if (parent instanceof ImmutableScope immParent) {
37 var flatParent = immParent.flattened();
38 var newDefs = new HashMap<>(flatParent.definitions);
39 newDefs.putAll(definitions);
40 return new ImmutableScope(flatParent.parent, newDefs);
41 }
42
43 return this;
44 }
45}
diff --git a/orang/src/main/java/lv/enes/orang/Main.java b/orang/src/main/java/lv/enes/orang/Main.java
index 7175dac..9a061fe 100644
--- a/orang/src/main/java/lv/enes/orang/Main.java
+++ b/orang/src/main/java/lv/enes/orang/Main.java
@@ -1,5 +1,6 @@
1package lv.enes.orang; 1package lv.enes.orang;
2 2
3import lv.enes.orang.checker.Checker;
3import lv.enes.orang.core.OrangException; 4import lv.enes.orang.core.OrangException;
4import lv.enes.orang.parser.Parser; 5import lv.enes.orang.parser.Parser;
5 6
@@ -17,11 +18,13 @@ public class Main {
17 } 18 }
18 19
19 private static void repl() throws IOException { 20 private static void repl() throws IOException {
21 var checker = Checker.of(Builtins.BUILTINS);
20 var evaluator = new Evaluator(); 22 var evaluator = new Evaluator();
21 23
22 try (var stream = Main.class.getResourceAsStream("prelude.orang")) { 24 try (var stream = Main.class.getResourceAsStream("prelude.orang")) {
23 var prog = Parser.parseProgram(stream); 25 var prog = Parser.parseProgram(stream);
24 evaluator = evaluator.visitProgram(prog); 26 checker = checker.visit(prog);
27 evaluator = evaluator.visit(prog);
25 } catch (OrangException ex) { 28 } catch (OrangException ex) {
26 STDOUT.println(STR."While evaluating prelude: \{ex}"); 29 STDOUT.println(STR."While evaluating prelude: \{ex}");
27 throw new RuntimeException(ex); 30 throw new RuntimeException(ex);
@@ -51,7 +54,8 @@ public class Main {
51 var filename = line.substring(2).trim(); 54 var filename = line.substring(2).trim();
52 try (var reader = new FileReader((filename))) { 55 try (var reader = new FileReader((filename))) {
53 var prog = Parser.parseProgram(reader); 56 var prog = Parser.parseProgram(reader);
54 evaluator = evaluator.visitProgram(prog); 57 checker = checker.visit(prog);
58 evaluator = evaluator.visit(prog);
55 } catch (IOException | OrangException ex) { 59 } catch (IOException | OrangException ex) {
56 STDOUT.println(ex); 60 STDOUT.println(ex);
57 } 61 }
@@ -67,7 +71,8 @@ public class Main {
67 71
68 try { 72 try {
69 var prog = Parser.parseReplProgram(line); 73 var prog = Parser.parseReplProgram(line);
70 evaluator = evaluator.visitProgram(prog); 74 checker = checker.visit(prog);
75 evaluator = evaluator.visit(prog);
71 if (evaluator.lastResult() != null) { 76 if (evaluator.lastResult() != null) {
72 STDOUT.print("-> "); 77 STDOUT.print("-> ");
73 STDOUT.println(evaluator.lastResult().stringify()); 78 STDOUT.println(evaluator.lastResult().stringify());
diff --git a/orang/src/main/java/lv/enes/orang/MutableScope.java b/orang/src/main/java/lv/enes/orang/MutableScope.java
deleted file mode 100644
index 8d900a4..0000000
--- a/orang/src/main/java/lv/enes/orang/MutableScope.java
+++ /dev/null
@@ -1,24 +0,0 @@
1package lv.enes.orang;
2
3import lv.enes.orang.value.Value;
4
5import java.util.HashMap;
6import java.util.Map;
7
8public class MutableScope extends Scope {
9 public static MutableScope of(Scope parent) {
10 return new MutableScope(parent, Map.of());
11 }
12
13 public static MutableScope of(Scope parent, String name, Value value) {
14 return new MutableScope(parent, Map.of(name, value));
15 }
16
17 protected MutableScope(Scope parent, Map<String, Value> definitions) {
18 super(parent, new HashMap<>(definitions));
19 }
20
21 public void setDefinition(String key, Value value) {
22 definitions.put(key, value);
23 }
24}
diff --git a/orang/src/main/java/lv/enes/orang/value/Array.java b/orang/src/main/java/lv/enes/orang/value/Array.java
index c3b645d..33e1516 100644
--- a/orang/src/main/java/lv/enes/orang/value/Array.java
+++ b/orang/src/main/java/lv/enes/orang/value/Array.java
@@ -1,6 +1,6 @@
1package lv.enes.orang.value; 1package lv.enes.orang.value;
2 2
3import lv.enes.orang.OrangRuntimeException; 3import lv.enes.orang.core.OrangRuntimeException;
4 4
5import java.util.ArrayList; 5import java.util.ArrayList;
6import java.util.Collections; 6import java.util.Collections;
diff --git a/orang/src/main/java/lv/enes/orang/value/BuiltinFunction.java b/orang/src/main/java/lv/enes/orang/value/BuiltinFunction.java
index 92ccc2e..1a61cfb 100644
--- a/orang/src/main/java/lv/enes/orang/value/BuiltinFunction.java
+++ b/orang/src/main/java/lv/enes/orang/value/BuiltinFunction.java
@@ -1,6 +1,6 @@
1package lv.enes.orang.value; 1package lv.enes.orang.value;
2 2
3import lv.enes.orang.OrangRuntimeException; 3import lv.enes.orang.core.OrangRuntimeException;
4 4
5import java.util.List; 5import java.util.List;
6 6
diff --git a/orang/src/main/java/lv/enes/orang/value/Function.java b/orang/src/main/java/lv/enes/orang/value/Function.java
index 6e3c83a..d0500b9 100644
--- a/orang/src/main/java/lv/enes/orang/value/Function.java
+++ b/orang/src/main/java/lv/enes/orang/value/Function.java
@@ -1,11 +1,12 @@
1package lv.enes.orang.value; 1package lv.enes.orang.value;
2 2
3import lv.enes.orang.*;
4import lv.enes.orang.ast.ArgSpec; 3import lv.enes.orang.ast.ArgSpec;
5import lv.enes.orang.ast.Expression; 4import lv.enes.orang.ast.Expression;
5import lv.enes.orang.core.OrangRuntimeException;
6import lv.enes.orang.core.Scope;
6import lv.enes.orang.utils.NonEmptyList; 7import lv.enes.orang.utils.NonEmptyList;
7 8
8public record Function(Scope scope, NonEmptyList<ArgSpec> args, Expression body) implements Value { 9public record Function(Scope<Value> scope, NonEmptyList<ArgSpec> args, Expression body) implements Value {
9 @Override 10 @Override
10 public String typeName() { 11 public String typeName() {
11 return "Function"; 12 return "Function";
diff --git a/orang/src/main/java/lv/enes/orang/value/OrangBoolean.java b/orang/src/main/java/lv/enes/orang/value/OrangBoolean.java
index 8a4776c..59aa9b7 100644
--- a/orang/src/main/java/lv/enes/orang/value/OrangBoolean.java
+++ b/orang/src/main/java/lv/enes/orang/value/OrangBoolean.java
@@ -1,7 +1,7 @@
1package lv.enes.orang.value; 1package lv.enes.orang.value;
2 2
3import lombok.EqualsAndHashCode; 3import lombok.EqualsAndHashCode;
4import lv.enes.orang.OrangRuntimeException; 4import lv.enes.orang.core.OrangRuntimeException;
5 5
6@EqualsAndHashCode 6@EqualsAndHashCode
7public final class OrangBoolean implements Value { 7public final class OrangBoolean implements Value {
diff --git a/orang/src/main/java/lv/enes/orang/value/OrangInteger.java b/orang/src/main/java/lv/enes/orang/value/OrangInteger.java
index 9b8d505..63a44da 100644
--- a/orang/src/main/java/lv/enes/orang/value/OrangInteger.java
+++ b/orang/src/main/java/lv/enes/orang/value/OrangInteger.java
@@ -1,6 +1,6 @@
1package lv.enes.orang.value; 1package lv.enes.orang.value;
2 2
3import lv.enes.orang.OrangRuntimeException; 3import lv.enes.orang.core.OrangRuntimeException;
4 4
5public record OrangInteger(int value) implements Value { 5public record OrangInteger(int value) implements Value {
6 @Override 6 @Override
diff --git a/orang/src/main/java/lv/enes/orang/value/OrangString.java b/orang/src/main/java/lv/enes/orang/value/OrangString.java
index c03f7ac..b4ede1f 100644
--- a/orang/src/main/java/lv/enes/orang/value/OrangString.java
+++ b/orang/src/main/java/lv/enes/orang/value/OrangString.java
@@ -1,6 +1,6 @@
1package lv.enes.orang.value; 1package lv.enes.orang.value;
2 2
3import lv.enes.orang.OrangRuntimeException; 3import lv.enes.orang.core.OrangRuntimeException;
4 4
5public record OrangString(String value) implements Value { 5public record OrangString(String value) implements Value {
6 @Override 6 @Override
diff --git a/orang/src/main/java/lv/enes/orang/value/PartialBuiltinFunction.java b/orang/src/main/java/lv/enes/orang/value/PartialBuiltinFunction.java
index 37278a4..c1be22a 100644
--- a/orang/src/main/java/lv/enes/orang/value/PartialBuiltinFunction.java
+++ b/orang/src/main/java/lv/enes/orang/value/PartialBuiltinFunction.java
@@ -1,6 +1,6 @@
1package lv.enes.orang.value; 1package lv.enes.orang.value;
2 2
3import lv.enes.orang.OrangRuntimeException; 3import lv.enes.orang.core.OrangRuntimeException;
4 4
5import java.util.ArrayList; 5import java.util.ArrayList;
6import java.util.Collections; 6import java.util.Collections;
diff --git a/orang/src/main/java/lv/enes/orang/value/PartialFunction.java b/orang/src/main/java/lv/enes/orang/value/PartialFunction.java
index cee0cd4..e73ba0c 100644
--- a/orang/src/main/java/lv/enes/orang/value/PartialFunction.java
+++ b/orang/src/main/java/lv/enes/orang/value/PartialFunction.java
@@ -3,10 +3,13 @@ package lv.enes.orang.value;
3import lv.enes.orang.*; 3import lv.enes.orang.*;
4import lv.enes.orang.ast.ArgSpec; 4import lv.enes.orang.ast.ArgSpec;
5import lv.enes.orang.ast.Expression; 5import lv.enes.orang.ast.Expression;
6import lv.enes.orang.core.MutableScope;
7import lv.enes.orang.core.OrangRuntimeException;
8import lv.enes.orang.core.Scope;
6import lv.enes.orang.utils.NonEmptyList; 9import lv.enes.orang.utils.NonEmptyList;
7 10
8public record PartialFunction(Scope scope, NonEmptyList<ArgSpec> remainingArgs, Expression body) implements Value { 11public record PartialFunction(Scope<Value> scope, NonEmptyList<ArgSpec> remainingArgs, Expression body) implements Value {
9 public static Value of(Scope scope, NonEmptyList<ArgSpec> remainingArgs, Expression body, Value param) throws OrangRuntimeException { 12 public static Value of(Scope<Value> scope, NonEmptyList<ArgSpec> remainingArgs, Expression body, Value param) throws OrangRuntimeException {
10 var spec = remainingArgs.getFirst(); 13 var spec = remainingArgs.getFirst();
11 var newScope = MutableScope.of(scope); 14 var newScope = MutableScope.of(scope);
12 switch (spec.type) { 15 switch (spec.type) {
diff --git a/orang/src/main/java/lv/enes/orang/value/Value.java b/orang/src/main/java/lv/enes/orang/value/Value.java
index 0816dc2..07e6848 100644
--- a/orang/src/main/java/lv/enes/orang/value/Value.java
+++ b/orang/src/main/java/lv/enes/orang/value/Value.java
@@ -1,6 +1,6 @@
1package lv.enes.orang.value; 1package lv.enes.orang.value;
2 2
3import lv.enes.orang.OrangRuntimeException; 3import lv.enes.orang.core.OrangRuntimeException;
4 4
5public sealed interface Value 5public sealed interface Value
6 permits Array, BuiltinFunction, Function, Nothing, OrangBoolean, OrangInteger, OrangString, PartialBuiltinFunction, PartialFunction, Undefined { 6 permits Array, BuiltinFunction, Function, Nothing, OrangBoolean, OrangInteger, OrangString, PartialBuiltinFunction, PartialFunction, Undefined {
diff --git a/orang/src/main/java/module-info.java b/orang/src/main/java/module-info.java
index 353d0dd..5b7b601 100644
--- a/orang/src/main/java/module-info.java
+++ b/orang/src/main/java/module-info.java
@@ -3,6 +3,7 @@ module lv.enes.orang {
3 exports lv.enes.orang.value; 3 exports lv.enes.orang.value;
4 4
5 requires lv.enes.orang.ast; 5 requires lv.enes.orang.ast;
6 requires lv.enes.orang.checker;
6 requires lv.enes.orang.core; 7 requires lv.enes.orang.core;
7 requires lv.enes.orang.parser; 8 requires lv.enes.orang.parser;
8 requires lv.enes.orang.utils; 9 requires lv.enes.orang.utils;
diff --git a/settings.gradle.kts b/settings.gradle.kts
index 391d33b..a64dfa6 100644
--- a/settings.gradle.kts
+++ b/settings.gradle.kts
@@ -1,3 +1,3 @@
1rootProject.name = "orang" 1rootProject.name = "orang"
2 2
3include("ast", "core", "lexer", "orang", "parser", "utils") \ No newline at end of file 3include("ast", "checker", "core", "lexer", "orang", "parser", "utils") \ No newline at end of file