-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathTypes.affine
More file actions
241 lines (214 loc) · 6.39 KB
/
Copy pathTypes.affine
File metadata and controls
241 lines (214 loc) · 6.39 KB
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
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
// SPDX-License-Identifier: MPL-2.0
// Types.affine — core type definitions for Error-Lang
// Ported from compiler/src/Types.res. Port conventions:
// * ReScript inline-record variants -> positional constructor args.
// * array<T> -> [T]; option<T> -> Option<T>; dict<k,v> -> Dict<k,v>; tuples kept.
// * Token variants `Float`/`String` renamed `FloatTok`/`StringTok`
// (`Float`/`String` are reserved type keywords in AffineScript).
//
// This is the `Types` module; sibling compiler modules `use Types::{...}`.
// Cross-module struct field access requires the affinescript module-resolver
// fix in patches/affinescript-module-struct-fields.patch.
module Types;
use prelude::*;
pub struct Position {
line: Int,
column: Int,
offset: Int
}
pub struct Location {
start: Position,
end_: Position,
file: String
}
pub enum TokenType {
// Keywords
Main, End, Let, Mutable, Function, Struct, If, Elseif, Else, While, For, In,
Break, Continue, Return, And, Or, Not, True, False, Nil, Gutter, Fn,
// Types
TInt, TFloat, TString, TBool, TArray, TEcho, TEchoR,
// Literals
Integer(Int),
FloatTok(Float), // ReScript Float(float)
StringTok(String), // ReScript String(string)
Identifier(String),
// Operators
Plus, Minus, Star, Slash, Percent, EqualEqual, BangEqual, Less, Greater,
LessEqual, GreaterEqual, Ampersand, Pipe, Caret, Tilde, LessLess, GreaterGreater,
Equal, Arrow, Question, Colon,
// Delimiters
LParen, RParen, LBracket, RBracket, LBrace, RBrace, Comma, Dot,
// Special
Newline, EOF, Error(String)
}
pub struct Token {
type_: TokenType,
lexeme: String,
loc: Location
}
// ============================================
// AST
// ============================================
pub enum Expr {
IntLit(Int, Location),
FloatLit(Float, Location),
StringLit(String, Location),
BoolLit(Bool, Location),
NilLit(Location),
Ident(String, Location),
Array([Expr], Location),
Binary(Expr, BinaryOp, Expr, Location),
Unary(UnaryOp, Expr, Location),
Call(Expr, [Expr], Location),
Index(Expr, Expr, Location),
Member(Expr, String, Location),
Ternary(Expr, Expr, Expr, Location),
Lambda([Param], Option<TypeExpr>, LambdaBody, Location)
}
pub enum BinaryOp {
Add, Sub, Mul, Div, Mod,
Eq, Neq, Lt, Gt, Lte, Gte,
BAnd, BOr, BXor, Shl, Shr,
LAnd, LOr
}
pub enum UnaryOp { Neg, LNot, BNot }
pub struct Param {
name: String,
type_: Option<TypeExpr>,
loc: Location
}
pub enum TypeExpr {
TyInt,
TyFloat,
TyString,
TyBool,
TyArray(TypeExpr),
// Echo types (Trope-IR-ready, see docs/Trope-Particularity-Integration.adoc):
// TyEcho ~ Trope[Phi] (retained witness)
// TyEchoResidue ~ FloatingQuality (witness severed)
TyEcho(Option<TypeExpr>, Option<TypeExpr>),
TyEchoResidue(Option<TypeExpr>, Option<TypeExpr>),
TyIdent(String)
}
pub enum LambdaBody {
LambdaExpr(Expr),
LambdaBlock([Stmt])
}
pub enum Stmt {
// inline records -> positional: (mutable_, name, type_, value, loc)
LetStmt(Bool, String, Option<TypeExpr>, Expr, Location),
// (target, value, loc)
AssignStmt(Expr, Expr, Location),
// (cond, then_, elseifs, else_, loc)
IfStmt(Expr, [Stmt], [(Expr, [Stmt])], Option<[Stmt]>, Location),
// (cond, body, loc)
WhileStmt(Expr, [Stmt], Location),
// (var, iter, body, loc)
ForStmt(String, Expr, [Stmt], Location),
// (value, loc)
ReturnStmt(Option<Expr>, Location),
BreakStmt(Location),
ContinueStmt(Location),
// (println, args, loc)
PrintStmt(Bool, [Expr], Location),
// (tokens, recovered, loc)
GutterBlock([Token], Bool, Location),
ExprStmt(Expr)
}
pub enum Decl {
// (name, params, returnType, body, loc)
FunctionDecl(String, [Param], Option<TypeExpr>, [Stmt], Location),
// (name, fields, loc)
StructDecl(String, [(String, TypeExpr)], Location),
// (body, loc)
MainBlock([Stmt], Location),
StmtDecl(Stmt)
}
pub struct Program {
declarations: [Decl],
loc: Location
}
// ============================================
// Errors
// ============================================
pub enum ErrorCode {
E0001, E0002, E0003, E0004, E0005, E0006, E0007, E0008, E0009, E0010
}
pub struct Diagnostic {
code: ErrorCode,
message: String,
loc: Location,
runNumber: Int,
hint: Option<String>
}
// ============================================
// Runtime state & stability
// ============================================
pub enum StabilityFactor {
MutableState(Int, Int), // mutations, readers
TypeInstability(Int), // reassignments
NullPropagation(Int), // depth
GlobalState(Int, Int), // mutations, dependencies
UnhandledError(Int), // paths
AlgorithmComplexity(Float), // time_ms
MemoryLeak(Int), // bytes
RaceCondition(Int) // conflicts
}
pub struct StabilityReport {
score: Int,
factors: [StabilityFactor],
breakdown: Dict<String, Int>,
recommendations: [String]
}
pub struct RuntimeState {
runCounter: Int,
stabilityScore: Int,
lastError: Option<ErrorCode>,
seed: Int,
stabilityFactors: [StabilityFactor],
discoveredRules: [String],
historicalRuns: [Int]
}
pub fn make_default_state() -> RuntimeState {
#{
runCounter: 0,
stabilityScore: 100,
lastError: None,
seed: 0,
stabilityFactors: [],
discoveredRules: [],
historicalRuns: []
}
}
// Stability impact (non-positive), mirrors Types.res `stabilityImpact`.
pub fn stability_impact(factor: StabilityFactor) -> Int {
match factor {
MutableState(mutations, readers) => -(10 * mutations + 5 * readers),
TypeInstability(reassignments) => -(15 * reassignments),
NullPropagation(depth) => -(20 * depth),
GlobalState(mutations, dependencies) => -(30 * mutations + 5 * dependencies),
UnhandledError(paths) => -(25 * paths),
AlgorithmComplexity(time_ms) => -trunc(time_ms / 10.0),
MemoryLeak(bytes) => -(10 * (bytes / 1024)),
RaceCondition(conflicts) => -(40 * conflicts)
}
}
// mirrors Types.res `calculateStability`: max(0, 100 + sum(impacts))
pub fn calculate_stability(factors: [StabilityFactor]) -> Int {
let penalties = fold(factors, 0, |acc, x| acc + stability_impact(x));
max(0, 100 + penalties)
}
pub fn error_code_to_string(code: ErrorCode) -> String {
match code {
E0001 => "E0001",
E0002 => "E0002",
E0003 => "E0003",
E0004 => "E0004",
E0005 => "E0005",
E0006 => "E0006",
E0007 => "E0007",
E0008 => "E0008",
E0009 => "E0009",
E0010 => "E0010"
}
}