Movatterモバイル変換


[0]ホーム

URL:


Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

Commitf4d5c20

Browse files
committed
arch: modular type parser
1 parentb300ef6 commitf4d5c20

File tree

10 files changed

+2677
-72
lines changed

10 files changed

+2677
-72
lines changed

‎CHANGELOG.md‎

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,12 @@
66
- The`xsize` property of collections has been renamed to`count`.
77
- The`xcontains()` method of collections has been renamed to`contains()`.
88
- Handling of dictionaries (`["Dictionary"] expressions and`{dict:...}`
9-
shorthand) has been improved. shorthand) has been improved.
9+
shorthand) has been improved.
10+
11+
##New Features and Improvements
12+
13+
- Refactored the type parser to use a modular architecture. This allows for
14+
better extensibility and maintainability of the type system.
1015

1116
##0.30.2_2025-07-15_
1217

‎simple-benchmark.ts‎

Lines changed: 96 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,96 @@
1+
import{parseType}from'./src/common/type/parse';
2+
3+
// Test cases covering different complexity levels
4+
consttestCases=[
5+
{name:'Simple primitives',types:['boolean','integer','string','number']},
6+
{name:'Collections',types:['list<integer>','tuple<string, number>','record<name: string>']},
7+
{name:'Function signatures',types:['(number) -> number','(x: number, y: number) -> number','(number+) -> number']},
8+
{name:'Union types',types:['string | number','boolean | integer | string','list<string> | record<name: string>']},
9+
{name:'Intersection types',types:['list<string> & record<length: integer>','(string | number) & (boolean | integer)']},
10+
{name:'Complex nested',types:[
11+
'list<tuple<string, record<id: integer, data: list<number>>>>',
12+
'record<users: list<record<name: string, posts: list<record<title: string, content: string>>>>>'
13+
]}
14+
];
15+
16+
functionbenchmarkTypeCategory(categoryName:string,types:string[],iterations=1000){
17+
console.log(`\n📊 Testing${categoryName}:`);
18+
console.log('-'.repeat(80));
19+
20+
constresults=[];
21+
22+
for(consttypeStringoftypes){
23+
conststart=process.hrtime.bigint();
24+
25+
for(leti=0;i<iterations;i++){
26+
try{
27+
parseType(typeString);
28+
}catch(e){
29+
// Ignore parse errors for benchmarking
30+
}
31+
}
32+
33+
constend=process.hrtime.bigint();
34+
consttimeMs=Number(end-start)/1_000_000;
35+
constavgTimeMs=timeMs/iterations;
36+
37+
results.push({
38+
type:typeString,
39+
totalTime:timeMs,
40+
avgTime:avgTimeMs,
41+
iterations
42+
});
43+
44+
consttruncatedType=typeString.length>60 ?typeString.substring(0,57)+'...' :typeString;
45+
console.log(`${truncatedType.padEnd(60)}${avgTimeMs.toFixed(4)}ms`);
46+
}
47+
48+
constavgForCategory=results.reduce((sum,r)=>sum+r.avgTime,0)/results.length;
49+
console.log(`${'AVERAGE'.padEnd(60)}${avgForCategory.toFixed(4)}ms`);
50+
51+
returnresults;
52+
}
53+
54+
functionmain(){
55+
console.log('🚀 Type Parser Performance Analysis\n');
56+
console.log('Measuring performance of the current modular parser implementation');
57+
58+
constiterations=1000;
59+
console.log(`Running${iterations} iterations per test case...\n`);
60+
61+
constallResults=[];
62+
63+
for(constcategoryoftestCases){
64+
constresults=benchmarkTypeCategory(category.name,category.types,iterations);
65+
allResults.push(...results);
66+
}
67+
68+
// Overall summary
69+
console.log('\n'+'='.repeat(80));
70+
console.log('📈 OVERALL PERFORMANCE SUMMARY');
71+
console.log('='.repeat(80));
72+
73+
consttotalAvgTime=allResults.reduce((sum,r)=>sum+r.avgTime,0)/allResults.length;
74+
constfastest=allResults.reduce((min,r)=>r.avgTime<min.avgTime ?r :min);
75+
constslowest=allResults.reduce((max,r)=>r.avgTime>max.avgTime ?r :max);
76+
77+
console.log(`Average parse time across all types:${totalAvgTime.toFixed(4)}ms`);
78+
console.log(`Fastest:${fastest.type} (${fastest.avgTime.toFixed(4)}ms)`);
79+
console.log(`Slowest:${slowest.type} (${slowest.avgTime.toFixed(4)}ms)`);
80+
console.log(`Performance ratio (slowest/fastest):${(slowest.avgTime/fastest.avgTime).toFixed(2)}x`);
81+
82+
// Performance characteristics
83+
console.log('\n🔍 Performance Characteristics:');
84+
constprimitiveTime=allResults.filter(r=>['boolean','integer','string','number'].includes(r.type))
85+
.reduce((sum,r)=>sum+r.avgTime,0)/4;
86+
constcomplexTime=allResults.filter(r=>r.type.includes('record<users:'))
87+
.reduce((sum,r)=>sum+r.avgTime,0)||allResults[allResults.length-1].avgTime;
88+
89+
console.log(`• Simple primitives average:${primitiveTime.toFixed(4)}ms`);
90+
console.log(`• Complex nested types:${complexTime.toFixed(4)}ms`);
91+
console.log(`• Complexity overhead:${(complexTime/primitiveTime).toFixed(2)}x`);
92+
93+
console.log('\n✅ Performance analysis complete!');
94+
}
95+
96+
main();

‎src/common/type/ast-nodes.ts‎

Lines changed: 240 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,240 @@
1+
exportinterfaceASTNode{
2+
kind:string;
3+
position:number;
4+
line:number;
5+
column:number;
6+
}
7+
8+
exportinterfaceNamedElementNodeextendsASTNode{
9+
kind:'named_element';
10+
name?:string;
11+
type:TypeNode;
12+
}
13+
14+
exportinterfaceArgumentNodeextendsASTNode{
15+
kind:'argument';
16+
element:NamedElementNode;
17+
modifier?:'optional'|'variadic_zero'|'variadic_one';
18+
}
19+
20+
exportinterfaceFunctionSignatureNodeextendsASTNode{
21+
kind:'function_signature';
22+
arguments:ArgumentNode[];
23+
returnType:TypeNode;
24+
}
25+
26+
exportinterfaceUnionTypeNodeextendsASTNode{
27+
kind:'union';
28+
types:TypeNode[];
29+
}
30+
31+
exportinterfaceIntersectionTypeNodeextendsASTNode{
32+
kind:'intersection';
33+
types:TypeNode[];
34+
}
35+
36+
exportinterfaceNegationTypeNodeextendsASTNode{
37+
kind:'negation';
38+
type:TypeNode;
39+
}
40+
41+
exportinterfaceGroupTypeNodeextendsASTNode{
42+
kind:'group';
43+
type:TypeNode;
44+
}
45+
46+
exportinterfaceListTypeNodeextendsASTNode{
47+
kind:'list';
48+
elementType:TypeNode;
49+
dimensions?:DimensionNode[];
50+
}
51+
52+
exportinterfaceVectorTypeNodeextendsASTNode{
53+
kind:'vector';
54+
elementType:TypeNode;
55+
size?:number;
56+
}
57+
58+
exportinterfaceMatrixTypeNodeextendsASTNode{
59+
kind:'matrix';
60+
elementType:TypeNode;
61+
dimensions?:DimensionNode[];
62+
}
63+
64+
exportinterfaceTensorTypeNodeextendsASTNode{
65+
kind:'tensor';
66+
elementType:TypeNode;
67+
}
68+
69+
exportinterfaceTupleTypeNodeextendsASTNode{
70+
kind:'tuple';
71+
elements:NamedElementNode[];
72+
}
73+
74+
exportinterfaceRecordTypeNodeextendsASTNode{
75+
kind:'record';
76+
entries:RecordEntryNode[];
77+
}
78+
79+
exportinterfaceRecordEntryNodeextendsASTNode{
80+
kind:'record_entry';
81+
key:string;
82+
valueType:TypeNode;
83+
}
84+
85+
exportinterfaceDictionaryTypeNodeextendsASTNode{
86+
kind:'dictionary';
87+
valueType:TypeNode;
88+
}
89+
90+
exportinterfaceSetTypeNodeextendsASTNode{
91+
kind:'set';
92+
elementType:TypeNode;
93+
}
94+
95+
exportinterfaceCollectionTypeNodeextendsASTNode{
96+
kind:'collection';
97+
elementType:TypeNode;
98+
indexed?:boolean;
99+
}
100+
101+
exportinterfaceExpressionTypeNodeextendsASTNode{
102+
kind:'expression';
103+
operator:string;
104+
}
105+
106+
exportinterfaceSymbolTypeNodeextendsASTNode{
107+
kind:'symbol';
108+
name:string;
109+
}
110+
111+
exportinterfaceNumericTypeNodeextendsASTNode{
112+
kind:'numeric';
113+
baseType:string;
114+
lowerBound?:ValueNode;
115+
upperBound?:ValueNode;
116+
}
117+
118+
exportinterfacePrimitiveTypeNodeextendsASTNode{
119+
kind:'primitive';
120+
name:string;
121+
}
122+
123+
exportinterfaceTypeReferenceNodeextendsASTNode{
124+
kind:'type_reference';
125+
name:string;
126+
isForward?:boolean;
127+
}
128+
129+
exportinterfaceValueNodeextendsASTNode{
130+
kind:'value';
131+
value:any;
132+
valueType:'string'|'number'|'boolean'|'infinity'|'nan';
133+
}
134+
135+
exportinterfaceDimensionNodeextendsASTNode{
136+
kind:'dimension';
137+
size:number|null;// null for '?'
138+
}
139+
140+
exportinterfaceIdentifierNodeextendsASTNode{
141+
kind:'identifier';
142+
name:string;
143+
}
144+
145+
exportinterfaceVerbatimStringNodeextendsASTNode{
146+
kind:'verbatim_string';
147+
value:string;
148+
}
149+
150+
exporttypeTypeNode=
151+
|FunctionSignatureNode
152+
|UnionTypeNode
153+
|IntersectionTypeNode
154+
|NegationTypeNode
155+
|GroupTypeNode
156+
|ListTypeNode
157+
|VectorTypeNode
158+
|MatrixTypeNode
159+
|TensorTypeNode
160+
|TupleTypeNode
161+
|RecordTypeNode
162+
|DictionaryTypeNode
163+
|SetTypeNode
164+
|CollectionTypeNode
165+
|ExpressionTypeNode
166+
|SymbolTypeNode
167+
|NumericTypeNode
168+
|PrimitiveTypeNode
169+
|TypeReferenceNode
170+
|ValueNode;
171+
172+
exportinterfaceASTVisitor<T>{
173+
visitFunctionSignature(node:FunctionSignatureNode):T;
174+
visitUnionType(node:UnionTypeNode):T;
175+
visitIntersectionType(node:IntersectionTypeNode):T;
176+
visitNegationType(node:NegationTypeNode):T;
177+
visitGroupType(node:GroupTypeNode):T;
178+
visitListType(node:ListTypeNode):T;
179+
visitVectorType(node:VectorTypeNode):T;
180+
visitMatrixType(node:MatrixTypeNode):T;
181+
visitTensorType(node:TensorTypeNode):T;
182+
visitTupleType(node:TupleTypeNode):T;
183+
visitRecordType(node:RecordTypeNode):T;
184+
visitDictionaryType(node:DictionaryTypeNode):T;
185+
visitSetType(node:SetTypeNode):T;
186+
visitCollectionType(node:CollectionTypeNode):T;
187+
visitExpressionType(node:ExpressionTypeNode):T;
188+
visitSymbolType(node:SymbolTypeNode):T;
189+
visitNumericType(node:NumericTypeNode):T;
190+
visitPrimitiveType(node:PrimitiveTypeNode):T;
191+
visitTypeReference(node:TypeReferenceNode):T;
192+
visitValue(node:ValueNode):T;
193+
}
194+
195+
exportfunctionvisitNode<T>(node:TypeNode,visitor:ASTVisitor<T>):T{
196+
switch(node.kind){
197+
case'function_signature':
198+
returnvisitor.visitFunctionSignature(node);
199+
case'union':
200+
returnvisitor.visitUnionType(node);
201+
case'intersection':
202+
returnvisitor.visitIntersectionType(node);
203+
case'negation':
204+
returnvisitor.visitNegationType(node);
205+
case'group':
206+
returnvisitor.visitGroupType(node);
207+
case'list':
208+
returnvisitor.visitListType(node);
209+
case'vector':
210+
returnvisitor.visitVectorType(node);
211+
case'matrix':
212+
returnvisitor.visitMatrixType(node);
213+
case'tensor':
214+
returnvisitor.visitTensorType(node);
215+
case'tuple':
216+
returnvisitor.visitTupleType(node);
217+
case'record':
218+
returnvisitor.visitRecordType(node);
219+
case'dictionary':
220+
returnvisitor.visitDictionaryType(node);
221+
case'set':
222+
returnvisitor.visitSetType(node);
223+
case'collection':
224+
returnvisitor.visitCollectionType(node);
225+
case'expression':
226+
returnvisitor.visitExpressionType(node);
227+
case'symbol':
228+
returnvisitor.visitSymbolType(node);
229+
case'numeric':
230+
returnvisitor.visitNumericType(node);
231+
case'primitive':
232+
returnvisitor.visitPrimitiveType(node);
233+
case'type_reference':
234+
returnvisitor.visitTypeReference(node);
235+
case'value':
236+
returnvisitor.visitValue(node);
237+
default:
238+
thrownewError(`Unknown node kind:${(nodeasany).kind}`);
239+
}
240+
}

0 commit comments

Comments
 (0)

[8]ページ先頭

©2009-2025 Movatter.jp