1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
use std::{ cell::RefCell, collections::{ HashMap, HashSet }, rc::Rc };
use crate::language::{ data::{ value::Value, types::TypeId }, text::location::Location };
pub enum Code
{
Push,
Execute,
// Evaluate a pipeline invocation without launching it; leave [callable, arguments].
PreparePipelineCall,
Pipeline(Rc<CompiledPipeline>),
// Consume a symbol reference and publish it in the current module (`pub visible`).
PublishSymbol,
// Operand: [stream (1 stdout, 2 stderr, 3 both), variable, pending targets].
BeginRedirect,
EndRedirect,
// Execute a command reference/name, or read bytes from a file path.
RedirectSource,
// Pop a command name; leave its result, or the unresolved string, in last_result.
TryExecute,
// Execute last_result only when it is a string marked executable; preserve other values.
// Boolean(true) rejects collections in a standalone variable statement whose value is
// discarded.
ExecuteIfExecutable,
MakeExecutable,
// Operand: [compiled function template, names of free bindings to capture].
MakeClosure,
ExitFunction,
NewVariable,
// Widen and validate the stack top without consuming it, before replacing a binding.
ValidateType,
// Operand: [name, type ID or None, argument index, optional default value].
BindParameter,
// Operand: [name, type ID or None, first extra argument index].
BindRestParameter,
SetVariable,
GetVariable,
PushResult,
PopResult,
CheckResult,
NewAlias,
ExportVariable,
GlobFiles,
ExpandArray,
// Stack operations: collect values, read an element, or update a variable's element.
MakeArray,
// Pop one array, validate its exact length, then push its elements in source order.
UnpackArray,
MakeHashMap,
// Operand is [type ID, field indexes in evaluation order].
MakeStruct,
// Operand is [checked field index or dynamic name, visible method versions].
// Consume a receiver reference; read data or invoke a method without explicit arguments.
GetField,
// Receiver references use a separate VM stack and never become language values.
ReferenceVariable,
ReferenceValue,
ReferenceField,
ReferenceIndex,
// Boolean operands enable/disable implicit calls; integer 1 enables data-field calls only.
ReferenceGroup,
// Like GetField, but preserve a bound method without invoking it.
BindField,
// Operand bits indicate a supplied start (1), end (2), and inclusive end (4).
MakeRange,
// Start captures a private receiver and the next_item method snapshot. Next
// pushes one non-None item and sets a boolean result for the linked jump.
StartIteration,
NextIteration,
// Pop a yielded value into a fresh scoped binding without assignment coercions.
BindIteration,
EndIteration,
// Operand is [continue target, break target]: labels before linking, numeric
// JumpTarget indexes afterwards. Enter pushes a loop frame; Exit pops it.
EnterLoop,
ExitLoop,
Break,
Continue,
GetElement,
SetElement,
ExpandPath,
InterpolateString,
InterpolateGlob,
EnterScope,
ExitScope,
MathAdd,
MathSubtract,
MathMultiply,
MathDivide,
MathModulo,
CompareEqual,
CompareNotEqual,
CompareLess,
CompareLessEqual,
CompareGreater,
CompareGreaterEqual,
// Pop a pattern, compare against the retained subject, and set last_result.
// A successful comparison also consumes the subject; failure keeps it for the next arm.
MatchPattern,
// Discard the stack top without treating an ExecResult as a command failure.
Discard,
MatchFail,
// Convert last_result in place; these instructions do not touch the value stack.
ToBoolean,
// Operand: [resolved target TypeId, visible factory versions, source constraint/signature].
ConvertType,
BooleanNot,
MathNegate,
// Before linking: label IDs local to this code vector. After linking: direct
// instruction indexes pointing at JumpTarget. Preserve last_result and the stack.
// Unconditional jumps also form loop back edges.
Jump,
JumpIfFalse,
JumpIfTrue,
// A labeled landing point during compilation; linking removes its operand.
JumpTarget
}
pub struct Instruction
{
pub location: Option<Location>,
pub code: Code,
pub operand: Option<Value>
}
pub struct PipelineBoundary
{
pub location: Location,
pub decode: Option<String>,
pub annotation: Option<String>,
pub type_id: Option<TypeId>,
pub conversions: Value,
}
pub struct PipelineRedirection
{
pub location: Location,
pub stream: i64,
pub variable: bool,
pub code: Vec<Instruction>,
}
pub struct PipelineStage
{
pub location: Location,
pub code: Vec<Instruction>,
pub call: bool,
pub command_word: bool,
pub explicit_arguments: bool,
pub input_used: bool,
pub property: bool,
pub destination: Option<String>,
pub redirects: Vec<PipelineRedirection>,
pub conversions: Value,
}
pub struct CompiledPipeline
{
pub stages: Vec<PipelineStage>,
pub boundaries: Vec<PipelineBoundary>,
}
pub struct Function
{
pub functions: FunctionBlockRef,
// Type owning an extension, including receiver-free conversion factories.
pub receiver_type: Option<TypeId>,
// A typedef default yields to a scripted factory when module interfaces overlap.
pub implied_conversion: bool,
pub arguments: Vec<String>,
pub argument_types: Vec<Option<TypeId>>,
pub minimum_arguments: usize,
pub variadic: bool,
pub return_type: Option<TypeId>,
pub code: Vec<Instruction>
}
#[derive(Clone)]
pub struct FunctionBlock
{
pub scope: String,
pub parent: Option<FunctionBlockRef>,
pub function_name: Option<String>,
pub declared_functions: HashSet<String>,
pub builtins: Rc<HashSet<&'static str>>,
pub functions: HashMap<String, FunctionRef>
}
pub type FunctionBlockRef = Rc<RefCell<FunctionBlock>>;
pub type FunctionRef = Rc<Function>;