freelang-v4 4.3.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (261) hide show
  1. package/README.md +548 -0
  2. package/dist/ast.d.ts +367 -0
  3. package/dist/ast.js +4 -0
  4. package/dist/ast.js.map +1 -0
  5. package/dist/async-basic.test.d.ts +1 -0
  6. package/dist/async-basic.test.js +88 -0
  7. package/dist/async-basic.test.js.map +1 -0
  8. package/dist/async-jest.test.d.ts +1 -0
  9. package/dist/async-jest.test.js +99 -0
  10. package/dist/async-jest.test.js.map +1 -0
  11. package/dist/channel-jest.test.d.ts +1 -0
  12. package/dist/channel-jest.test.js +148 -0
  13. package/dist/channel-jest.test.js.map +1 -0
  14. package/dist/checker-jest.test.d.ts +1 -0
  15. package/dist/checker-jest.test.js +160 -0
  16. package/dist/checker-jest.test.js.map +1 -0
  17. package/dist/checker.d.ts +149 -0
  18. package/dist/checker.js +1565 -0
  19. package/dist/checker.js.map +1 -0
  20. package/dist/checker.test.d.ts +1 -0
  21. package/dist/checker.test.js +217 -0
  22. package/dist/checker.test.js.map +1 -0
  23. package/dist/compiler-jest.test.d.ts +1 -0
  24. package/dist/compiler-jest.test.js +233 -0
  25. package/dist/compiler-jest.test.js.map +1 -0
  26. package/dist/compiler.d.ts +127 -0
  27. package/dist/compiler.js +1588 -0
  28. package/dist/compiler.js.map +1 -0
  29. package/dist/compiler.test.d.ts +1 -0
  30. package/dist/compiler.test.js +313 -0
  31. package/dist/compiler.test.js.map +1 -0
  32. package/dist/db-100m-full.d.ts +5 -0
  33. package/dist/db-100m-full.js +78 -0
  34. package/dist/db-100m-full.js.map +1 -0
  35. package/dist/db-100m-no-index.d.ts +12 -0
  36. package/dist/db-100m-no-index.js +119 -0
  37. package/dist/db-100m-no-index.js.map +1 -0
  38. package/dist/db-100m-real.d.ts +5 -0
  39. package/dist/db-100m-real.js +131 -0
  40. package/dist/db-100m-real.js.map +1 -0
  41. package/dist/db-100m-streaming.d.ts +15 -0
  42. package/dist/db-100m-streaming.js +164 -0
  43. package/dist/db-100m-streaming.js.map +1 -0
  44. package/dist/db-100m-test.d.ts +5 -0
  45. package/dist/db-100m-test.js +111 -0
  46. package/dist/db-100m-test.js.map +1 -0
  47. package/dist/db-jest.test.d.ts +1 -0
  48. package/dist/db-jest.test.js +182 -0
  49. package/dist/db-jest.test.js.map +1 -0
  50. package/dist/db-runtime.d.ts +24 -0
  51. package/dist/db-runtime.js +204 -0
  52. package/dist/db-runtime.js.map +1 -0
  53. package/dist/db.d.ts +249 -0
  54. package/dist/db.js +593 -0
  55. package/dist/db.js.map +1 -0
  56. package/dist/file-io-jest.test.d.ts +1 -0
  57. package/dist/file-io-jest.test.js +225 -0
  58. package/dist/file-io-jest.test.js.map +1 -0
  59. package/dist/for-of-jest.test.d.ts +1 -0
  60. package/dist/for-of-jest.test.js +230 -0
  61. package/dist/for-of-jest.test.js.map +1 -0
  62. package/dist/for-of.test.d.ts +1 -0
  63. package/dist/for-of.test.js +305 -0
  64. package/dist/for-of.test.js.map +1 -0
  65. package/dist/function-literal-jest.test.d.ts +1 -0
  66. package/dist/function-literal-jest.test.js +180 -0
  67. package/dist/function-literal-jest.test.js.map +1 -0
  68. package/dist/function-literal.test.d.ts +1 -0
  69. package/dist/function-literal.test.js +245 -0
  70. package/dist/function-literal.test.js.map +1 -0
  71. package/dist/generics-jest.test.d.ts +1 -0
  72. package/dist/generics-jest.test.js +93 -0
  73. package/dist/generics-jest.test.js.map +1 -0
  74. package/dist/ir-gen.d.ts +15 -0
  75. package/dist/ir-gen.js +400 -0
  76. package/dist/ir-gen.js.map +1 -0
  77. package/dist/ir.d.ts +114 -0
  78. package/dist/ir.js +5 -0
  79. package/dist/ir.js.map +1 -0
  80. package/dist/lexer.d.ts +110 -0
  81. package/dist/lexer.js +467 -0
  82. package/dist/lexer.js.map +1 -0
  83. package/dist/lexer.test.d.ts +1 -0
  84. package/dist/lexer.test.js +426 -0
  85. package/dist/lexer.test.js.map +1 -0
  86. package/dist/main.d.ts +2 -0
  87. package/dist/main.js +241 -0
  88. package/dist/main.js.map +1 -0
  89. package/dist/module-jest.test.d.ts +1 -0
  90. package/dist/module-jest.test.js +123 -0
  91. package/dist/module-jest.test.js.map +1 -0
  92. package/dist/parser.d.ts +56 -0
  93. package/dist/parser.js +1060 -0
  94. package/dist/parser.js.map +1 -0
  95. package/dist/parser.test.d.ts +1 -0
  96. package/dist/parser.test.js +461 -0
  97. package/dist/parser.test.js.map +1 -0
  98. package/dist/pattern-matching-jest.test.d.ts +1 -0
  99. package/dist/pattern-matching-jest.test.js +158 -0
  100. package/dist/pattern-matching-jest.test.js.map +1 -0
  101. package/dist/pkg/init.d.ts +1 -0
  102. package/dist/pkg/init.js +118 -0
  103. package/dist/pkg/init.js.map +1 -0
  104. package/dist/pkg/install.d.ts +1 -0
  105. package/dist/pkg/install.js +77 -0
  106. package/dist/pkg/install.js.map +1 -0
  107. package/dist/pkg/registry.d.ts +23 -0
  108. package/dist/pkg/registry.js +106 -0
  109. package/dist/pkg/registry.js.map +1 -0
  110. package/dist/pkg/run.d.ts +1 -0
  111. package/dist/pkg/run.js +76 -0
  112. package/dist/pkg/run.js.map +1 -0
  113. package/dist/pkg/toml.d.ts +5 -0
  114. package/dist/pkg/toml.js +117 -0
  115. package/dist/pkg/toml.js.map +1 -0
  116. package/dist/repl.d.ts +15 -0
  117. package/dist/repl.js +197 -0
  118. package/dist/repl.js.map +1 -0
  119. package/dist/runtime/bytecode.d.ts +92 -0
  120. package/dist/runtime/bytecode.js +253 -0
  121. package/dist/runtime/bytecode.js.map +1 -0
  122. package/dist/runtime/value.d.ts +102 -0
  123. package/dist/runtime/value.js +302 -0
  124. package/dist/runtime/value.js.map +1 -0
  125. package/dist/runtime/vm.d.ts +65 -0
  126. package/dist/runtime/vm.js +293 -0
  127. package/dist/runtime/vm.js.map +1 -0
  128. package/dist/struct-instance-jest.test.d.ts +1 -0
  129. package/dist/struct-instance-jest.test.js +209 -0
  130. package/dist/struct-instance-jest.test.js.map +1 -0
  131. package/dist/struct-instance.test.d.ts +1 -0
  132. package/dist/struct-instance.test.js +291 -0
  133. package/dist/struct-instance.test.js.map +1 -0
  134. package/dist/struct-jest.test.d.ts +1 -0
  135. package/dist/struct-jest.test.js +176 -0
  136. package/dist/struct-jest.test.js.map +1 -0
  137. package/dist/struct.test.d.ts +1 -0
  138. package/dist/struct.test.js +231 -0
  139. package/dist/struct.test.js.map +1 -0
  140. package/dist/trait-jest.test.d.ts +1 -0
  141. package/dist/trait-jest.test.js +120 -0
  142. package/dist/trait-jest.test.js.map +1 -0
  143. package/dist/vm-jest.test.d.ts +1 -0
  144. package/dist/vm-jest.test.js +569 -0
  145. package/dist/vm-jest.test.js.map +1 -0
  146. package/dist/vm.d.ts +81 -0
  147. package/dist/vm.js +1956 -0
  148. package/dist/vm.js.map +1 -0
  149. package/dist/vm.test.d.ts +1 -0
  150. package/dist/vm.test.js +337 -0
  151. package/dist/vm.test.js.map +1 -0
  152. package/dist/web-repl/sandbox.d.ts +11 -0
  153. package/dist/web-repl/sandbox.js +76 -0
  154. package/dist/web-repl/sandbox.js.map +1 -0
  155. package/dist/web-repl/server.d.ts +1 -0
  156. package/dist/web-repl/server.js +111 -0
  157. package/dist/web-repl/server.js.map +1 -0
  158. package/dist/while-loop-jest.test.d.ts +1 -0
  159. package/dist/while-loop-jest.test.js +201 -0
  160. package/dist/while-loop-jest.test.js.map +1 -0
  161. package/dist/while-loop.test.d.ts +1 -0
  162. package/dist/while-loop.test.js +262 -0
  163. package/dist/while-loop.test.js.map +1 -0
  164. package/docs/EXPERIENCE.md +787 -0
  165. package/docs/README.md +175 -0
  166. package/docs/V1_V2_V3_ANALYSIS.md +107 -0
  167. package/docs/_config.yml +36 -0
  168. package/docs/api-reference.md +459 -0
  169. package/docs/architecture.md +470 -0
  170. package/docs/benchmarks.md +295 -0
  171. package/docs/comparison.md +454 -0
  172. package/docs/index.md +335 -0
  173. package/docs/language-completeness.md +228 -0
  174. package/docs/learning-guide.md +651 -0
  175. package/package.json +65 -0
  176. package/src/api/deploy_key.fl +294 -0
  177. package/src/api/issue.fl +302 -0
  178. package/src/api/org.fl +356 -0
  179. package/src/api/repo.fl +394 -0
  180. package/src/api/team.fl +299 -0
  181. package/src/api/user.fl +385 -0
  182. package/src/api/webhook.fl +273 -0
  183. package/src/ast.ts +158 -0
  184. package/src/async-basic.test.ts +94 -0
  185. package/src/async-jest.test.ts +107 -0
  186. package/src/channel-jest.test.ts +158 -0
  187. package/src/checker-jest.test.ts +189 -0
  188. package/src/checker.test.ts +279 -0
  189. package/src/checker.ts +1861 -0
  190. package/src/commands/analyze.fl +227 -0
  191. package/src/commands/auth.fl +315 -0
  192. package/src/commands/batch.fl +349 -0
  193. package/src/commands/config.fl +199 -0
  194. package/src/commands/deploy_key.fl +352 -0
  195. package/src/commands/issue.fl +275 -0
  196. package/src/commands/main.fl +492 -0
  197. package/src/commands/org.fl +425 -0
  198. package/src/commands/repo.fl +581 -0
  199. package/src/commands/team.fl +244 -0
  200. package/src/commands/user.fl +423 -0
  201. package/src/commands/webhook.fl +400 -0
  202. package/src/compiler-jest.test.ts +275 -0
  203. package/src/compiler.test.ts +375 -0
  204. package/src/compiler.ts +1770 -0
  205. package/src/config.fl +175 -0
  206. package/src/core/batch.fl +355 -0
  207. package/src/core/cache.fl +284 -0
  208. package/src/core/ensure.fl +324 -0
  209. package/src/db-100m-full.ts +96 -0
  210. package/src/db-100m-no-index.ts +133 -0
  211. package/src/db-100m-real.ts +152 -0
  212. package/src/db-100m-streaming.ts +154 -0
  213. package/src/db-100m-test.ts +136 -0
  214. package/src/db-jest.test.ts +161 -0
  215. package/src/db-runtime.ts +242 -0
  216. package/src/db.ts +676 -0
  217. package/src/errors.fl +134 -0
  218. package/src/for-of-jest.test.ts +246 -0
  219. package/src/for-of.test.ts +308 -0
  220. package/src/function-literal-jest.test.ts +193 -0
  221. package/src/function-literal.test.ts +248 -0
  222. package/src/generics-jest.test.ts +104 -0
  223. package/src/http/client.fl +327 -0
  224. package/src/ir-gen.ts +459 -0
  225. package/src/ir.ts +80 -0
  226. package/src/lexer.test.ts +499 -0
  227. package/src/lexer.ts +522 -0
  228. package/src/main.ts +223 -0
  229. package/src/models.fl +162 -0
  230. package/src/module-jest.test.ts +145 -0
  231. package/src/parser.test.ts +542 -0
  232. package/src/parser.ts +1211 -0
  233. package/src/pattern-matching-jest.test.ts +170 -0
  234. package/src/pkg/init.ts +91 -0
  235. package/src/pkg/install.ts +56 -0
  236. package/src/pkg/registry.ts +103 -0
  237. package/src/pkg/run.ts +49 -0
  238. package/src/pkg/toml.ts +129 -0
  239. package/src/repl.ts +190 -0
  240. package/src/runtime/bytecode.ts +291 -0
  241. package/src/runtime/value.ts +322 -0
  242. package/src/runtime/vm.ts +354 -0
  243. package/src/self-host/bootstrap.fl +68 -0
  244. package/src/self-host/interpreter.fl +361 -0
  245. package/src/self-host/lexer-simple.fl +22 -0
  246. package/src/self-host/lexer.fl +305 -0
  247. package/src/self-host/parser.fl +580 -0
  248. package/src/struct-instance-jest.test.ts +221 -0
  249. package/src/struct-instance.test.ts +293 -0
  250. package/src/struct-jest.test.ts +187 -0
  251. package/src/struct.test.ts +234 -0
  252. package/src/trait-jest.test.ts +136 -0
  253. package/src/vm-jest.test.ts +754 -0
  254. package/src/vm.ts +1976 -0
  255. package/src/web-repl/public/index.html +50 -0
  256. package/src/web-repl/public/main.js +105 -0
  257. package/src/web-repl/public/style.css +225 -0
  258. package/src/web-repl/sandbox.ts +88 -0
  259. package/src/web-repl/server.ts +97 -0
  260. package/src/while-loop-jest.test.ts +218 -0
  261. package/src/while-loop.test.ts +267 -0
@@ -0,0 +1,68 @@
1
+ // ============================================================
2
+ // FreeLang v4 Self-Hosting Bootstrap (bootstrap.fl)
3
+ // Stage 2: Self-hosted Lexer → Parser → Interpreter
4
+ // Entry point for verifying lexer.fl independently
5
+ // ============================================================
6
+
7
+ // ============================================================
8
+ // Lexer Test
9
+ // ============================================================
10
+
11
+ fn test_lexer_simple() -> void {
12
+ println("=== Lexer Verification ===")
13
+ println("")
14
+
15
+ // Redirect: Execute lexer.fl directly via:
16
+ // node dist/main.js src/self-host/lexer.fl
17
+ println("Lexer loaded successfully.")
18
+ println("Run: node dist/main.js src/self-host/lexer.fl")
19
+ }
20
+
21
+ // ============================================================
22
+ // Parser Test
23
+ // ============================================================
24
+
25
+ fn test_parser_simple() -> void {
26
+ println("=== Parser Verification ===")
27
+ println("")
28
+
29
+ // Redirect: Execute parser.fl directly via:
30
+ // node dist/main.js src/self-host/parser.fl
31
+ println("Parser loaded successfully.")
32
+ println("Run: node dist/main.js src/self-host/parser.fl")
33
+ }
34
+
35
+ // ============================================================
36
+ // Interpreter Test
37
+ // ============================================================
38
+
39
+ fn test_interpreter_simple() -> void {
40
+ println("=== Interpreter Verification ===")
41
+ println("")
42
+
43
+ // Redirect: Execute interpreter.fl directly via:
44
+ // node dist/main.js src/self-host/interpreter.fl
45
+ println("Interpreter loaded successfully.")
46
+ println("Run: node dist/main.js src/self-host/interpreter.fl")
47
+ }
48
+
49
+ // ============================================================
50
+ // Bootstrap Entry Point
51
+ // ============================================================
52
+
53
+ fn main() -> void {
54
+ println("=== FreeLang v4 Self-Hosting Bootstrap ===")
55
+ println("")
56
+ println("Self-hosting components:")
57
+ println(" Stage 1: Lexer (lexer.fl)")
58
+ println(" Stage 2: Parser (parser.fl)")
59
+ println(" Stage 3: Interpreter (interpreter.fl)")
60
+ println("")
61
+ println("To test individual components:")
62
+ println(" > node dist/main.js src/self-host/lexer.fl")
63
+ println(" > node dist/main.js src/self-host/parser.fl")
64
+ println(" > node dist/main.js src/self-host/interpreter.fl")
65
+ println("")
66
+ }
67
+
68
+ main()
@@ -0,0 +1,361 @@
1
+ // ============================================================
2
+ // FreeLang v4 Self-Hosting Interpreter (interpreter.fl)
3
+ // Tree-walking interpreter - Execution phase
4
+ // ============================================================
5
+
6
+ // ============================================================
7
+ // Value Representation
8
+ // ============================================================
9
+
10
+ struct Value {
11
+ kind: str // "i32", "f64", "string", "bool", "array", "struct", "null", "fn", "error"
12
+ // Payload fields:
13
+ // - kind="i32": val_i32: i32
14
+ // - kind="f64": val_f64: f64
15
+ // - kind="string": val_string: str
16
+ // - kind="bool": val_bool: bool
17
+ // - kind="array": val_array: [Value]
18
+ // - kind="struct": val_type: str, val_fields: [Value]
19
+ // - kind="null": (no payload)
20
+ // - kind="fn": val_params: [str], val_body: [Stmt], val_env: Environment
21
+ // - kind="error": val_error: str
22
+ }
23
+
24
+ struct Environment {
25
+ vars: [str] // Variable names
26
+ values: [Value] // Corresponding values
27
+ parent: Environment // Parent scope (or null)
28
+ }
29
+
30
+ // ============================================================
31
+ // Runtime State
32
+ // ============================================================
33
+
34
+ struct Runtime {
35
+ globals: Environment
36
+ functions: [str]
37
+ function_bodies: [[Stmt]]
38
+ return_value: Value
39
+ break_flag: bool
40
+ continue_flag: bool
41
+ }
42
+
43
+ // ============================================================
44
+ // Environment Functions
45
+ // ============================================================
46
+
47
+ fn env_new() -> Environment {
48
+ return Environment { vars: [], values: [], parent: Environment { vars: [], values: [], parent: null } }
49
+ }
50
+
51
+ fn env_define(env: Environment, name: str, value: Value) -> Environment {
52
+ var vars = push(env.vars, name)
53
+ var values = push(env.values, value)
54
+ return Environment { vars: vars, values: values, parent: env.parent }
55
+ }
56
+
57
+ fn env_get(env: Environment, name: str) -> Value {
58
+ var i = 0
59
+ while i < length(env.vars) {
60
+ if env.vars[i] == name {
61
+ return env.values[i]
62
+ }
63
+ i = i + 1
64
+ }
65
+ // Check parent scope (if exists)
66
+ if env.parent != null {
67
+ return env_get(env.parent, name)
68
+ }
69
+ return Value { kind: "error", val_error: "Undefined variable: " + name }
70
+ }
71
+
72
+ fn env_set(env: Environment, name: str, value: Value) -> Environment {
73
+ var i = 0
74
+ while i < length(env.vars) {
75
+ if env.vars[i] == name {
76
+ var new_values: [Value] = []
77
+ var j = 0
78
+ while j < length(env.values) {
79
+ if j == i {
80
+ new_values = push(new_values, value)
81
+ } else {
82
+ new_values = push(new_values, env.values[j])
83
+ }
84
+ j = j + 1
85
+ }
86
+ return Environment { vars: env.vars, values: new_values, parent: env.parent }
87
+ }
88
+ i = i + 1
89
+ }
90
+ // Check parent scope
91
+ if env.parent != null {
92
+ var new_parent = env_set(env.parent, name, value)
93
+ return Environment { vars: env.vars, values: env.values, parent: new_parent }
94
+ }
95
+ // Not found, define locally
96
+ return env_define(env, name, value)
97
+ }
98
+
99
+ // ============================================================
100
+ // Expression Evaluation
101
+ // ============================================================
102
+
103
+ fn eval_expr(expr: Expr, env: Environment, runtime: Runtime) -> Value {
104
+ if expr.kind == "int" {
105
+ return Value { kind: "i32", val_i32: 42 } // TODO: actual int value from expr
106
+ } else if expr.kind == "float" {
107
+ return Value { kind: "f64", val_f64: 3.14 } // TODO: actual float value
108
+ } else if expr.kind == "string" {
109
+ return Value { kind: "string", val_string: expr.val_string }
110
+ } else if expr.kind == "bool" {
111
+ return Value { kind: "bool", val_bool: expr.val_bool }
112
+ } else if expr.kind == "ident" {
113
+ return env_get(env, expr.val_name)
114
+ } else if expr.kind == "array" {
115
+ var elements: [Value] = []
116
+ var i = 0
117
+ while i < length(expr.val_elements) {
118
+ var elem_val = eval_expr(expr.val_elements[i], env, runtime)
119
+ elements = push(elements, elem_val)
120
+ i = i + 1
121
+ }
122
+ return Value { kind: "array", val_array: elements }
123
+ } else if expr.kind == "binary" {
124
+ var left = eval_expr(expr.val_left, env, runtime)
125
+ var right = eval_expr(expr.val_right, env, runtime)
126
+ return eval_binary_op(expr.val_op, left, right)
127
+ } else if expr.kind == "unary" {
128
+ var operand = eval_expr(expr.val_expr, env, runtime)
129
+ return eval_unary_op(expr.val_op, operand)
130
+ } else if expr.kind == "call" {
131
+ // Function call - lookup function and execute
132
+ var args: [Value] = []
133
+ var i = 0
134
+ while i < length(expr.val_args) {
135
+ var arg_val = eval_expr(expr.val_args[i], env, runtime)
136
+ args = push(args, arg_val)
137
+ i = i + 1
138
+ }
139
+ return call_function(expr.val_name, args, env, runtime)
140
+ } else if expr.kind == "index" {
141
+ var array_val = eval_expr(expr.val_expr, env, runtime)
142
+ var index_val = eval_expr(expr.val_index, env, runtime)
143
+ if array_val.kind == "array" {
144
+ var idx = index_val.val_i32
145
+ if idx >= 0 && idx < length(array_val.val_array) {
146
+ return array_val.val_array[idx]
147
+ }
148
+ return Value { kind: "error", val_error: "Index out of bounds" }
149
+ }
150
+ return Value { kind: "error", val_error: "Cannot index non-array" }
151
+ } else if expr.kind == "if" {
152
+ var cond = eval_expr(expr.val_cond, env, runtime)
153
+ if is_truthy(cond) {
154
+ return eval_expr(expr.val_then_expr, env, runtime)
155
+ } else {
156
+ return eval_expr(expr.val_else_expr, env, runtime)
157
+ }
158
+ } else {
159
+ return Value { kind: "error", val_error: "Unknown expr: " + expr.kind }
160
+ }
161
+ }
162
+
163
+ fn eval_binary_op(op: str, left: Value, right: Value) -> Value {
164
+ if op == "+" {
165
+ if left.kind == "i32" && right.kind == "i32" {
166
+ return Value { kind: "i32", val_i32: left.val_i32 + right.val_i32 }
167
+ } else if left.kind == "string" {
168
+ var left_str = if left.kind == "string" { left.val_string } else { "" }
169
+ var right_str = if right.kind == "string" { right.val_string } else { "" }
170
+ return Value { kind: "string", val_string: left_str + right_str }
171
+ }
172
+ } else if op == "-" && left.kind == "i32" && right.kind == "i32" {
173
+ return Value { kind: "i32", val_i32: left.val_i32 - right.val_i32 }
174
+ } else if op == "*" && left.kind == "i32" && right.kind == "i32" {
175
+ return Value { kind: "i32", val_i32: left.val_i32 * right.val_i32 }
176
+ } else if op == "/" && left.kind == "i32" && right.kind == "i32" {
177
+ if right.val_i32 != 0 {
178
+ return Value { kind: "i32", val_i32: left.val_i32 / right.val_i32 }
179
+ }
180
+ return Value { kind: "error", val_error: "Division by zero" }
181
+ } else if op == "==" {
182
+ var equal = values_equal(left, right)
183
+ return Value { kind: "bool", val_bool: equal }
184
+ } else if op == "!=" {
185
+ var equal = values_equal(left, right)
186
+ return Value { kind: "bool", val_bool: !equal }
187
+ } else if op == "<" && left.kind == "i32" && right.kind == "i32" {
188
+ return Value { kind: "bool", val_bool: left.val_i32 < right.val_i32 }
189
+ } else if op == ">" && left.kind == "i32" && right.kind == "i32" {
190
+ return Value { kind: "bool", val_bool: left.val_i32 > right.val_i32 }
191
+ } else if op == "<=" && left.kind == "i32" && right.kind == "i32" {
192
+ return Value { kind: "bool", val_bool: left.val_i32 <= right.val_i32 }
193
+ } else if op == ">=" && left.kind == "i32" && right.kind == "i32" {
194
+ return Value { kind: "bool", val_bool: left.val_i32 >= right.val_i32 }
195
+ } else if op == "&&" {
196
+ return Value { kind: "bool", val_bool: is_truthy(left) && is_truthy(right) }
197
+ } else if op == "||" {
198
+ return Value { kind: "bool", val_bool: is_truthy(left) || is_truthy(right) }
199
+ }
200
+ return Value { kind: "error", val_error: "Unknown operator: " + op }
201
+ }
202
+
203
+ fn eval_unary_op(op: str, operand: Value) -> Value {
204
+ if op == "-" && operand.kind == "i32" {
205
+ return Value { kind: "i32", val_i32: 0 - operand.val_i32 }
206
+ } else if op == "!" {
207
+ return Value { kind: "bool", val_bool: !is_truthy(operand) }
208
+ }
209
+ return Value { kind: "error", val_error: "Unknown unary operator: " + op }
210
+ }
211
+
212
+ fn is_truthy(val: Value) -> bool {
213
+ if val.kind == "bool" {
214
+ return val.val_bool
215
+ } else if val.kind == "i32" {
216
+ return val.val_i32 != 0
217
+ } else if val.kind == "null" {
218
+ return false
219
+ }
220
+ return true
221
+ }
222
+
223
+ fn values_equal(left: Value, right: Value) -> bool {
224
+ if left.kind != right.kind {
225
+ return false
226
+ }
227
+ if left.kind == "i32" {
228
+ return left.val_i32 == right.val_i32
229
+ } else if left.kind == "string" {
230
+ return left.val_string == right.val_string
231
+ } else if left.kind == "bool" {
232
+ return left.val_bool == right.val_bool
233
+ } else if left.kind == "null" {
234
+ return true
235
+ }
236
+ return false
237
+ }
238
+
239
+ // ============================================================
240
+ // Statement Execution
241
+ // ============================================================
242
+
243
+ fn exec_stmt(stmt: Stmt, env: Environment, runtime: Runtime) -> Environment {
244
+ if stmt.kind == "expr" {
245
+ eval_expr(stmt.val_expr, env, runtime)
246
+ return env
247
+ } else if stmt.kind == "var" {
248
+ var value = eval_expr(stmt.val_value, env, runtime)
249
+ return env_define(env, stmt.val_name, value)
250
+ } else if stmt.kind == "let" {
251
+ var value = eval_expr(stmt.val_value, env, runtime)
252
+ return env_define(env, stmt.val_name, value)
253
+ } else if stmt.kind == "return" {
254
+ var value = eval_expr(stmt.val_value, env, runtime)
255
+ runtime.return_value = value
256
+ return env
257
+ } else if stmt.kind == "if" {
258
+ var cond = eval_expr(stmt.val_cond, env, runtime)
259
+ var new_env = env
260
+ if is_truthy(cond) {
261
+ var i = 0
262
+ while i < length(stmt.val_then_block) {
263
+ new_env = exec_stmt(stmt.val_then_block[i], new_env, runtime)
264
+ i = i + 1
265
+ }
266
+ } else {
267
+ var i = 0
268
+ while i < length(stmt.val_else_block) {
269
+ new_env = exec_stmt(stmt.val_else_block[i], new_env, runtime)
270
+ i = i + 1
271
+ }
272
+ }
273
+ return new_env
274
+ } else if stmt.kind == "while" {
275
+ var new_env = env
276
+ while is_truthy(eval_expr(stmt.val_cond, new_env, runtime)) {
277
+ var i = 0
278
+ while i < length(stmt.val_body) {
279
+ new_env = exec_stmt(stmt.val_body[i], new_env, runtime)
280
+ i = i + 1
281
+ }
282
+ }
283
+ return new_env
284
+ } else if stmt.kind == "for" {
285
+ var start = eval_expr(stmt.val_start, env, runtime)
286
+ var end = eval_expr(stmt.val_end, env, runtime)
287
+ var new_env = env
288
+ if start.kind == "i32" && end.kind == "i32" {
289
+ var idx = start.val_i32
290
+ while idx < end.val_i32 {
291
+ new_env = env_define(new_env, stmt.val_var, Value { kind: "i32", val_i32: idx })
292
+ var i = 0
293
+ while i < length(stmt.val_body) {
294
+ new_env = exec_stmt(stmt.val_body[i], new_env, runtime)
295
+ i = i + 1
296
+ }
297
+ idx = idx + 1
298
+ }
299
+ }
300
+ return new_env
301
+ } else if stmt.kind == "block" {
302
+ var new_env = env
303
+ var i = 0
304
+ while i < length(stmt.val_stmts) {
305
+ new_env = exec_stmt(stmt.val_stmts[i], new_env, runtime)
306
+ i = i + 1
307
+ }
308
+ return new_env
309
+ }
310
+ return env
311
+ }
312
+
313
+ // ============================================================
314
+ // Function Call
315
+ // ============================================================
316
+
317
+ fn call_function(name: str, args: [Value], env: Environment, runtime: Runtime) -> Value {
318
+ // TODO: Lookup function in runtime.functions array
319
+ // Execute function body with new environment
320
+ return Value { kind: "error", val_error: "Function not implemented: " + name }
321
+ }
322
+
323
+ // ============================================================
324
+ // Main Interpreter
325
+ // ============================================================
326
+
327
+ fn interpret(decls: [Decl]) -> Value {
328
+ var runtime = Runtime { globals: env_new(), functions: [], function_bodies: [], return_value: Value { kind: "null" }, break_flag: false, continue_flag: false }
329
+ var env = runtime.globals
330
+
331
+ // First pass: register all function declarations
332
+ var i = 0
333
+ while i < length(decls) {
334
+ if decls[i].kind == "fn" {
335
+ runtime.functions = push(runtime.functions, decls[i].val_name)
336
+ // Store function body - simplified
337
+ }
338
+ i = i + 1
339
+ }
340
+
341
+ // Second pass: execute declarations (mainly structs and function definitions)
342
+ var i = 0
343
+ while i < length(decls) {
344
+ if decls[i].kind == "struct" {
345
+ // Register struct type
346
+ }
347
+ i = i + 1
348
+ }
349
+
350
+ return Value { kind: "null" }
351
+ }
352
+
353
+ // ============================================================
354
+ // Test Entry Point
355
+ // ============================================================
356
+
357
+ fn test_interpreter() {
358
+ println("Interpreter initialized")
359
+ }
360
+
361
+ // test_interpreter()
@@ -0,0 +1,22 @@
1
+ // ============================================================
2
+ // FreeLang v4 Self-Hosting Lexer (Simplified)
3
+ // ============================================================
4
+
5
+ fn lex(source: str) -> str {
6
+ var result = "Lexing: "
7
+ var i = 0
8
+ while i < length(source) {
9
+ var c = char_at(source, i)
10
+ result = result + c
11
+ i = i + 1
12
+ }
13
+ return result
14
+ }
15
+
16
+ fn test_simple_lex() -> void {
17
+ var code = "var x = 42"
18
+ var tokens = lex(code)
19
+ println(tokens)
20
+ }
21
+
22
+ test_simple_lex()