-
Notifications
You must be signed in to change notification settings - Fork 35
/
instructions.h
176 lines (145 loc) · 5.72 KB
/
instructions.h
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
#pragma once
#include "../enum.h"
namespace tr::instructions {
enum OP {
Noop,
Jump, //arbitrary jump, used at the beginning to jump over storage-data (storage-data's addresses are constant)
Halt,
SourceMap, //one parameter (size uint32). all subsequent bytes withing the given size is a map op:pos:end, each uint32
Main, //marks end of meta-data section (subroutine metadata + storage data). after this the body section with all subroutine ops follow.
Never,
Any,
Unknown,
Void, //void is reserved word
Object,
String,
Number,
Boolean,
BigInt,
Symbol,
Null,
Undefined,
StringLiteral,
NumberLiteral,
BigIntLiteral,
True,
False,
Function,
FunctionRef, //one parameter, the index of the subroutine of the function that needs to be instantiated
ClassRef,
Method,
MethodSignature,
Parameter,
Initializer,
Property,
PropertySignature,
Class,
ObjectLiteral,
IndexSignature,
PropertyAccess,
Array,
Tuple,
TupleMember,
TupleNamedMember, //has one parameter, the name in the storage
Optional,
Readonly,
Static,
Rest,
RestReuse, //in expressions like [...T, x] indicates that T can be stolen instead of copied
Union,
Intersection,
Extends, //expected 2 entries on the stack
Condition, //expected 3 entries on the stack
JumpCondition, //expected 1 entry on the stack + two uint16 parameters
CallExpression, //JS call expression, with 1 parameter (amount of parameters)
Instantiate, //instantiates a type on the stack (FunctionRef for example), ExpressionWithTypeArguments
StartInferTypeArguments, //calling generic function/class with only value arguments, infer type arguments from it
InferTypeArguments,
New,
/**
* Reserved new stack entries to be used as type variables.
*
* 1 parameter indicating how many stack entries will be reserved.
*/
Slots,
/**
* Self checks an expression, like variable, class, interface, type, etc.
* TypeScript checks types even if they are never used. This SelfCheck makes sure all expression are visited at least once in main.
*/
SelfCheck,
///**
// * Stack parameter. For each JS variable, JS function, as well as type variables (mapped-type variable for example).
// *
// * Parameters:
// * 1. address on initial stack frame, which should contain its name as a string.
// * 3. modifier: const
// * 2. position in source code. necessary to determine if a reference is made to a const symbol before it was defined.
// */
//Var,
/**
* Makes sure that in the current variable slot is a type placed if nothing was provided as parameter.
*
* For each type argument like here `T` a TypeArgument OP is generated.
* Different to Var OP since Var does reserve an entry on the stack,
* whereas TypeArgument ensures there is a stack entry if not already provided via call parameters..
* ```typescript
* type A<T> = T;
* ```
*/
TypeArgument,
TypeArgumentDefault, //one parameter with the address of the subroutine of the default value
TypeArgumentConstraint, //expects an entry (the constraint) on the stack
TemplateLiteral,
IndexAccess,
Length,
KeyOf,
Infer,
TypeOf,
Widen, //literal to widened type, true -> boolean, '' => string, 32 => number, etc
/**
* Reserves a type variable on the stack, which contains a type object. Unknown as default.
*
* The address of it is known in the program and referenced directly.
*/
TypeVar,
Loads, //LOAD from stack. pushes to the stack a referenced type in the stack. has 2 parameters: <frame> <index>, frame is a negative offset to the frame, and index the index of the stack entry withing the referenced frame
Assign,
Dup, //Duplicates the current stack end
Set, //narrows/Sets a new value for a subroutine (variables)
SetAndPush, //narrows/Sets a new value for a subroutine (variables)
Error,
Pop,
Inline, //Execute a subroutine on the same active frame
//Frame, //creates a new stack frame
//FrameEnd,
Return, //end of a subroutine
ReturnStatement, //used in inferring return types of functions
Subroutine,
Distribute, //calls a subroutine for each union member. one parameter (address to subroutine)
Call, //call a subroutine and push the result on the stack
TailCall,
CheckBody,
InferBody,
UnwrapInferBody,
};
enum class ErrorCode {
CannotFind, //e.g. Cannot find name 'abc'
};
//Max 8 bits, used in the bytecode
enum SubroutineFlag: unsigned int {
};
}
template<>
struct fmt::formatter<tr::instructions::OP>: formatter<std::string_view> {
template<typename FormatContext>
auto format(tr::instructions::OP p, FormatContext &ctx) {
return formatter<string_view>::format(magic_enum::enum_name<tr::instructions::OP>(p), ctx);
}
};
template<>
struct fmt::formatter<tr::instructions::ErrorCode>: formatter<std::string_view> {
template<typename FormatContext>
auto format(tr::instructions::ErrorCode p, FormatContext &ctx) {
return formatter<string_view>::format(magic_enum::enum_name<tr::instructions::ErrorCode>(p), ctx);
}
};