fusion-lang 0.0.1.alpha1 → 0.0.1
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.
- checksums.yaml +4 -4
- data/README.md +19 -6
- data/Rakefile +9 -0
- data/docs/lang/design.md +418 -28
- data/docs/lang/implementation.md +238 -0
- data/docs/lang/roadmap.md +20 -57
- data/docs/user/explanation.md +5 -10
- data/docs/user/how-to-guides.md +62 -23
- data/docs/user/reference.md +596 -168
- data/docs/user/tutorial.md +32 -29
- data/examples/double.fsn +1 -1
- data/examples/ends.fsn +4 -0
- data/examples/factorial.fsn +2 -2
- data/examples/fizzbuzz.fsn +1 -4
- data/examples/json_test.fsn +4 -0
- data/examples/palindrome.fsn +2 -1
- data/exe/fusion +17 -44
- data/lib/fusion/ast.rb +97 -0
- data/lib/fusion/atom.rb +17 -0
- data/lib/fusion/cli/decoder.rb +84 -0
- data/lib/fusion/cli/encoder.rb +28 -0
- data/lib/fusion/cli/options.rb +212 -0
- data/lib/fusion/cli/parser.rb +38 -0
- data/lib/fusion/cli/repl.rb +78 -0
- data/lib/fusion/cli/serializer.rb +70 -0
- data/lib/fusion/cli.rb +207 -0
- data/lib/fusion/interpreter/builtins.rb +465 -0
- data/lib/fusion/interpreter/env.rb +89 -0
- data/lib/fusion/interpreter/error_val.rb +71 -0
- data/lib/fusion/interpreter/func.rb +22 -0
- data/lib/fusion/interpreter/native_func.rb +22 -0
- data/lib/fusion/interpreter/thunk.rb +53 -0
- data/lib/fusion/interpreter.rb +752 -0
- data/lib/fusion/lexer.rb +249 -0
- data/lib/fusion/null.rb +9 -0
- data/lib/fusion/parser.rb +542 -0
- data/lib/fusion/token.rb +22 -0
- data/lib/fusion/typed_data.rb +23 -0
- data/lib/fusion/version.rb +1 -1
- data/lib/fusion/wire_pair.rb +11 -0
- data/lib/fusion.rb +11 -1122
- data/stdlib/all.fsn +13 -0
- data/stdlib/any.fsn +12 -0
- data/stdlib/chars.fsn +5 -0
- data/stdlib/compact.fsn +6 -0
- data/stdlib/concat.fsn +5 -0
- data/stdlib/falsey.fsn +6 -0
- data/stdlib/filter.fsn +12 -0
- data/stdlib/flatten.fsn +7 -0
- data/stdlib/gt.fsn +9 -0
- data/stdlib/gte.fsn +9 -0
- data/stdlib/lt.fsn +9 -0
- data/stdlib/lte.fsn +9 -0
- data/stdlib/map.fsn +6 -2
- data/stdlib/range.fsn +2 -1
- data/stdlib/reduce.fsn +8 -0
- data/stdlib/sanitize.fsn +12 -0
- data/stdlib/truthy.fsn +7 -0
- metadata +41 -2
- data/stdlib/math/square.fsn +0 -1
|
@@ -0,0 +1,53 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
# === Interpreter internals ===
|
|
4
|
+
#
|
|
5
|
+
# Lazy, memoized value of a top-level unit (a file, or an inline/REPL entry).
|
|
6
|
+
|
|
7
|
+
module Fusion
|
|
8
|
+
class Interpreter
|
|
9
|
+
class Thunk
|
|
10
|
+
# We use a custom Ruby error to transmit read failures between `Interpreter.evaluate_file`
|
|
11
|
+
# (which runs in the @compute block) and the Thunk to enforce their connection.
|
|
12
|
+
# If `Interpreter.evaluate_file` were to be used outside of a Thunk, the Ruby error would
|
|
13
|
+
# bubble and trigger an `internal_error` later on.
|
|
14
|
+
class ReadFailure < StandardError; end
|
|
15
|
+
|
|
16
|
+
def initialize(&compute)
|
|
17
|
+
@compute = compute
|
|
18
|
+
@state = :unforced # :unforced | :forcing | :done
|
|
19
|
+
@value = nil # memoized result: runtime value/error | ReadFailure
|
|
20
|
+
end
|
|
21
|
+
|
|
22
|
+
# `operation`/`input`/`site` describe the @-reference forcing this thunk.
|
|
23
|
+
# They are NOT passed to `@compute`, because they differ when evaluating the same
|
|
24
|
+
# Thunk for different @-references. They MUST NOT become part or the memoized value.
|
|
25
|
+
def force(operation: "loading code", input: NULL, site: { origin: "code", file: nil })
|
|
26
|
+
result = case @state
|
|
27
|
+
when :done
|
|
28
|
+
@value
|
|
29
|
+
when :forcing
|
|
30
|
+
# Re-entering while still computing results in a non-productive data cycle. Not memoized.
|
|
31
|
+
ErrorVal.from_runtime(kind: "reference_error", **site, operation: operation, input: input, message: "non-productive data cycle")
|
|
32
|
+
when :unforced
|
|
33
|
+
@state = :forcing
|
|
34
|
+
begin
|
|
35
|
+
@value = @compute.call
|
|
36
|
+
rescue ReadFailure => failure
|
|
37
|
+
# Memoize the Ruby error itself. Turn it into a Fusion runtime error below.
|
|
38
|
+
@value = failure
|
|
39
|
+
end
|
|
40
|
+
@state = :done
|
|
41
|
+
@value
|
|
42
|
+
end
|
|
43
|
+
|
|
44
|
+
case result
|
|
45
|
+
when ReadFailure
|
|
46
|
+
ErrorVal.from_runtime(kind: "reference_error", **site, operation: operation, input: input, message: result.message)
|
|
47
|
+
else
|
|
48
|
+
result
|
|
49
|
+
end
|
|
50
|
+
end
|
|
51
|
+
end
|
|
52
|
+
end
|
|
53
|
+
end
|