@getlang/parser
Advanced tools
Comparing version 0.0.24 to 0.0.25
@@ -181,4 +181,4 @@ import type { Token as MooToken } from 'moo' | ||
name, | ||
optional, | ||
value, | ||
optional, | ||
}) | ||
@@ -236,4 +236,4 @@ | ||
body, | ||
typeInfo: { type: Type.Value }, | ||
context, | ||
typeInfo: { type: Type.Value }, | ||
}) | ||
@@ -254,6 +254,6 @@ | ||
kind: NodeKind.SelectorExpr, | ||
expand, | ||
selector, | ||
expand, | ||
typeInfo: { type: Type.Value }, | ||
context, | ||
typeInfo: { type: Type.Value }, | ||
}) | ||
@@ -269,4 +269,4 @@ | ||
options, | ||
typeInfo: { type: Type.Value }, | ||
context, | ||
typeInfo: { type: Type.Value }, | ||
}) | ||
@@ -280,4 +280,4 @@ | ||
entries, | ||
typeInfo: { type: Type.Value }, | ||
context, | ||
typeInfo: { type: Type.Value }, | ||
}) | ||
@@ -293,4 +293,4 @@ | ||
inputs, | ||
typeInfo: { type: Type.Value }, | ||
context, | ||
typeInfo: { type: Type.Value }, | ||
}) | ||
@@ -301,4 +301,4 @@ | ||
slice, | ||
typeInfo: { type: Type.Value }, | ||
context, | ||
typeInfo: { type: Type.Value }, | ||
}) | ||
@@ -325,10 +325,12 @@ | ||
requestExpr, | ||
functionExpr, | ||
identifierExpr, | ||
templateExpr, | ||
// CONTEXTUAL EXPRESSIONS | ||
selectorExpr, | ||
modifierExpr, | ||
sliceExpr, | ||
objectLiteralExpr, | ||
functionExpr, | ||
moduleCallExpr, | ||
objectLiteralExpr, | ||
sliceExpr, | ||
templateExpr, | ||
} |
@@ -10,8 +10,5 @@ export enum Type { | ||
Never = 'never', | ||
Maybe = 'maybe', | ||
} | ||
type ScalarType = { | ||
type: Exclude<Type, Type.List | Type.Struct> | ||
} | ||
export type List = { | ||
@@ -22,2 +19,7 @@ type: Type.List | ||
export type Maybe = { | ||
type: Type.Maybe | ||
option: TypeInfo | ||
} | ||
export type Struct = { | ||
@@ -28,4 +30,8 @@ type: Type.Struct | ||
export type TypeInfo = ScalarType | List | Struct | ||
type ScalarType = { | ||
type: Exclude<Type, Type.List | Type.Struct | Type.Maybe> | ||
} | ||
export type TypeInfo = ScalarType | List | Struct | Maybe | ||
export function tequal(a: TypeInfo, b: TypeInfo): boolean { | ||
@@ -42,2 +48,4 @@ if (a.type === 'list' && b.type === 'list') { | ||
}) | ||
} else if (a.type === 'maybe' && b.type === 'maybe') { | ||
return tequal(a.option, b.option) | ||
} else { | ||
@@ -44,0 +52,0 @@ return a.type === b.type |
@@ -6,3 +6,3 @@ import { | ||
} from '@getlang/utils' | ||
import { NodeKind, type CExpr, type Expr } from '../../ast/ast.js' | ||
import { NodeKind, type CExpr, type Expr, t } from '../../ast/ast.js' | ||
import { RootScope } from '../../ast/scope.js' | ||
@@ -19,21 +19,43 @@ import type { TransformVisitor, Visit } from '../../visitor/transform.js' | ||
function unwrap(typeInfo: TypeInfo) { | ||
if (typeInfo.type === Type.List) { | ||
return unwrap(typeInfo.of) | ||
switch (typeInfo.type) { | ||
case Type.List: | ||
return unwrap(typeInfo.of) | ||
case Type.Maybe: | ||
return unwrap(typeInfo.option) | ||
default: | ||
return typeInfo | ||
} | ||
return typeInfo | ||
} | ||
function rewrap( | ||
typeInfo: TypeInfo | undefined, | ||
itemTypeInfo: TypeInfo, | ||
): TypeInfo { | ||
if (typeInfo?.type !== Type.List) { | ||
return clone(itemTypeInfo) | ||
} | ||
return { ...typeInfo, of: rewrap(typeInfo.of, itemTypeInfo) } | ||
} | ||
export function inferTypeInfo(): TransformVisitor { | ||
const scope = new RootScope<Expr>() | ||
let optional = false | ||
function setOptional<T>(opt: boolean, cb: () => T): T { | ||
const last = optional | ||
optional = opt | ||
const ret = cb() | ||
optional = last | ||
return ret | ||
} | ||
function rewrap( | ||
typeInfo: TypeInfo | undefined, | ||
itemTypeInfo: TypeInfo, | ||
): TypeInfo { | ||
switch (typeInfo?.type) { | ||
case Type.List: | ||
return { ...typeInfo, of: rewrap(typeInfo.of, itemTypeInfo) } | ||
case Type.Maybe: { | ||
const option = rewrap(typeInfo.option, itemTypeInfo) | ||
if (option.type === Type.Maybe || !optional) { | ||
return option | ||
} | ||
return { ...typeInfo, option } | ||
} | ||
default: | ||
return clone(itemTypeInfo) | ||
} | ||
} | ||
function itemVisit(node: CExpr, visit: Visit): Visit { | ||
@@ -48,3 +70,3 @@ return child => { | ||
}) | ||
const xnode = visit(child) | ||
const xnode = setOptional(false, () => visit(child)) | ||
scope.popContext() | ||
@@ -61,2 +83,23 @@ return xnode | ||
InputDeclStmt: { | ||
enter(node, visit) { | ||
const xnode = { ...node } | ||
const dv = node.defaultValue | ||
xnode.defaultValue = dv && setOptional(node.optional, () => visit(dv)) | ||
const input = t.identifierExpr(node.id) | ||
if (node.optional) { | ||
input.typeInfo = { type: Type.Maybe, option: input.typeInfo } | ||
} | ||
scope.vars[node.id.value] = input | ||
return xnode | ||
}, | ||
}, | ||
AssignmentStmt: { | ||
enter(node, visit) { | ||
const value = setOptional(node.optional, () => visit(node.value)) | ||
return trace.AssignmentStmt({ ...node, value }) | ||
}, | ||
}, | ||
IdentifierExpr(node) { | ||
@@ -88,3 +131,4 @@ const id = node.value.value | ||
const xnode = trace.SliceExpr.enter(node, itemVisit(node, visit)) | ||
const typeInfo: TypeInfo = { type: Type.Value } | ||
let typeInfo: TypeInfo = { type: Type.Value } | ||
if (optional) typeInfo = { type: Type.Maybe, option: typeInfo } | ||
return { ...xnode, typeInfo: rewrap(xnode.context?.typeInfo, typeInfo) } | ||
@@ -94,10 +138,2 @@ }, | ||
ModuleCallExpr: { | ||
enter(node, visit) { | ||
const xnode = trace.ModuleCallExpr.enter(node, itemVisit(node, visit)) | ||
const typeInfo: TypeInfo = { type: Type.Value } | ||
return { ...xnode, typeInfo: rewrap(xnode.context?.typeInfo, typeInfo) } | ||
}, | ||
}, | ||
SelectorExpr: { | ||
@@ -109,2 +145,3 @@ enter(node, visit) { | ||
) | ||
if (typeInfo.type === Type.Struct) { | ||
@@ -120,3 +157,8 @@ typeInfo = selectTypeInfo(typeInfo, xnode.selector) ?? { | ||
} | ||
if (xnode.expand) typeInfo = { type: Type.List, of: typeInfo } | ||
if (xnode.expand) { | ||
typeInfo = { type: Type.List, of: typeInfo } | ||
} else if (optional) { | ||
typeInfo = { type: Type.Maybe, option: typeInfo } | ||
} | ||
return { ...xnode, typeInfo: rewrap(xnode.context?.typeInfo, typeInfo) } | ||
@@ -158,4 +200,13 @@ }, | ||
node, | ||
itemVisit(node, visit), | ||
itemVisit(node, child => { | ||
if (child === node.context) return visit(child) | ||
const entry = node.entries.find(e => e.value === child) | ||
invariant( | ||
entry, | ||
new QuerySyntaxError('Object entry missing typeinfo'), | ||
) | ||
return setOptional(entry.optional, () => visit(child)) | ||
}), | ||
) | ||
const typeInfo: TypeInfo = { | ||
@@ -175,6 +226,15 @@ type: Type.Struct, | ||
} | ||
return { ...xnode, typeInfo: rewrap(xnode.context?.typeInfo, typeInfo) } | ||
}, | ||
}, | ||
ModuleCallExpr: { | ||
enter(node, visit) { | ||
const xnode = trace.ModuleCallExpr.enter(node, itemVisit(node, visit)) | ||
const typeInfo: TypeInfo = { type: Type.Value } | ||
return { ...xnode, typeInfo: rewrap(xnode.context?.typeInfo, typeInfo) } | ||
}, | ||
}, | ||
} | ||
} |
@@ -139,11 +139,11 @@ import type { Token as MooToken } from 'moo'; | ||
requestExpr: (method: Token, url: Expr, headers: ObjectLiteralExpr, blocks: RequestBlocks, body: Expr) => RequestExpr; | ||
functionExpr: (body: Stmt[], context?: Expr) => FunctionExpr; | ||
identifierExpr: (value: Token) => IdentifierExpr; | ||
templateExpr: (elements: (Expr | Token)[]) => TemplateExpr; | ||
selectorExpr: (selector: TemplateExpr, expand: boolean, context?: Expr) => SelectorExpr; | ||
modifierExpr: (value: Token, options?: ObjectLiteralExpr, context?: Expr) => ModifierExpr; | ||
sliceExpr: (slice: Token, context?: Expr) => SliceExpr; | ||
objectLiteralExpr: (entries: ObjectEntry[], context?: Expr) => ObjectLiteralExpr; | ||
functionExpr: (body: Stmt[], context?: Expr) => FunctionExpr; | ||
moduleCallExpr: (name: Token, inputs?: Expr, context?: Expr) => ModuleCallExpr; | ||
objectLiteralExpr: (entries: ObjectEntry[], context?: Expr) => ObjectLiteralExpr; | ||
sliceExpr: (slice: Token, context?: Expr) => SliceExpr; | ||
templateExpr: (elements: (Expr | Token)[]) => TemplateExpr; | ||
}; | ||
export {}; |
@@ -28,4 +28,4 @@ import { Type } from './typeinfo.js'; | ||
name, | ||
optional, | ||
value, | ||
optional, | ||
}); | ||
@@ -66,4 +66,4 @@ const declImportStmt = (id) => ({ | ||
body, | ||
typeInfo: { type: Type.Value }, | ||
context, | ||
typeInfo: { type: Type.Value }, | ||
}); | ||
@@ -78,6 +78,6 @@ const identifierExpr = (value) => ({ | ||
kind: NodeKind.SelectorExpr, | ||
expand, | ||
selector, | ||
expand, | ||
typeInfo: { type: Type.Value }, | ||
context, | ||
typeInfo: { type: Type.Value }, | ||
}); | ||
@@ -88,4 +88,4 @@ const modifierExpr = (value, options = objectLiteralExpr([]), context) => ({ | ||
options, | ||
typeInfo: { type: Type.Value }, | ||
context, | ||
typeInfo: { type: Type.Value }, | ||
}); | ||
@@ -95,4 +95,4 @@ const objectLiteralExpr = (entries, context) => ({ | ||
entries, | ||
typeInfo: { type: Type.Value }, | ||
context, | ||
typeInfo: { type: Type.Value }, | ||
}); | ||
@@ -103,4 +103,4 @@ const moduleCallExpr = (name, inputs = objectLiteralExpr([]), context) => ({ | ||
inputs, | ||
typeInfo: { type: Type.Value }, | ||
context, | ||
typeInfo: { type: Type.Value }, | ||
}); | ||
@@ -110,4 +110,4 @@ const sliceExpr = (slice, context) => ({ | ||
slice, | ||
typeInfo: { type: Type.Value }, | ||
context, | ||
typeInfo: { type: Type.Value }, | ||
}); | ||
@@ -130,11 +130,12 @@ const templateExpr = (elements) => ({ | ||
requestExpr, | ||
functionExpr, | ||
identifierExpr, | ||
templateExpr, | ||
// CONTEXTUAL EXPRESSIONS | ||
selectorExpr, | ||
modifierExpr, | ||
sliceExpr, | ||
objectLiteralExpr, | ||
functionExpr, | ||
moduleCallExpr, | ||
objectLiteralExpr, | ||
sliceExpr, | ||
templateExpr, | ||
}; | ||
//# sourceMappingURL=ast.js.map |
@@ -9,7 +9,5 @@ export declare enum Type { | ||
Struct = "struct", | ||
Never = "never" | ||
Never = "never", | ||
Maybe = "maybe" | ||
} | ||
type ScalarType = { | ||
type: Exclude<Type, Type.List | Type.Struct>; | ||
}; | ||
export type List = { | ||
@@ -19,2 +17,6 @@ type: Type.List; | ||
}; | ||
export type Maybe = { | ||
type: Type.Maybe; | ||
option: TypeInfo; | ||
}; | ||
export type Struct = { | ||
@@ -24,4 +26,7 @@ type: Type.Struct; | ||
}; | ||
export type TypeInfo = ScalarType | List | Struct; | ||
type ScalarType = { | ||
type: Exclude<Type, Type.List | Type.Struct | Type.Maybe>; | ||
}; | ||
export type TypeInfo = ScalarType | List | Struct | Maybe; | ||
export declare function tequal(a: TypeInfo, b: TypeInfo): boolean; | ||
export {}; |
@@ -11,2 +11,3 @@ export var Type; | ||
Type["Never"] = "never"; | ||
Type["Maybe"] = "maybe"; | ||
})(Type || (Type = {})); | ||
@@ -27,2 +28,5 @@ export function tequal(a, b) { | ||
} | ||
else if (a.type === 'maybe' && b.type === 'maybe') { | ||
return tequal(a.option, b.option); | ||
} | ||
else { | ||
@@ -29,0 +33,0 @@ return a.type === b.type; |
import { invariant, QuerySyntaxError, ValueReferenceError, } from '@getlang/utils'; | ||
import { NodeKind } from '../../ast/ast.js'; | ||
import { NodeKind, t } from '../../ast/ast.js'; | ||
import { RootScope } from '../../ast/scope.js'; | ||
@@ -11,15 +11,36 @@ import { traceVisitor } from '../trace.js'; | ||
function unwrap(typeInfo) { | ||
if (typeInfo.type === Type.List) { | ||
return unwrap(typeInfo.of); | ||
switch (typeInfo.type) { | ||
case Type.List: | ||
return unwrap(typeInfo.of); | ||
case Type.Maybe: | ||
return unwrap(typeInfo.option); | ||
default: | ||
return typeInfo; | ||
} | ||
return typeInfo; | ||
} | ||
function rewrap(typeInfo, itemTypeInfo) { | ||
if (typeInfo?.type !== Type.List) { | ||
return clone(itemTypeInfo); | ||
} | ||
return { ...typeInfo, of: rewrap(typeInfo.of, itemTypeInfo) }; | ||
} | ||
export function inferTypeInfo() { | ||
const scope = new RootScope(); | ||
let optional = false; | ||
function setOptional(opt, cb) { | ||
const last = optional; | ||
optional = opt; | ||
const ret = cb(); | ||
optional = last; | ||
return ret; | ||
} | ||
function rewrap(typeInfo, itemTypeInfo) { | ||
switch (typeInfo?.type) { | ||
case Type.List: | ||
return { ...typeInfo, of: rewrap(typeInfo.of, itemTypeInfo) }; | ||
case Type.Maybe: { | ||
const option = rewrap(typeInfo.option, itemTypeInfo); | ||
if (option.type === Type.Maybe || !optional) { | ||
return option; | ||
} | ||
return { ...typeInfo, option }; | ||
} | ||
default: | ||
return clone(itemTypeInfo); | ||
} | ||
} | ||
function itemVisit(node, visit) { | ||
@@ -34,3 +55,3 @@ return child => { | ||
}); | ||
const xnode = visit(child); | ||
const xnode = setOptional(false, () => visit(child)); | ||
scope.popContext(); | ||
@@ -44,2 +65,21 @@ return xnode; | ||
...trace, | ||
InputDeclStmt: { | ||
enter(node, visit) { | ||
const xnode = { ...node }; | ||
const dv = node.defaultValue; | ||
xnode.defaultValue = dv && setOptional(node.optional, () => visit(dv)); | ||
const input = t.identifierExpr(node.id); | ||
if (node.optional) { | ||
input.typeInfo = { type: Type.Maybe, option: input.typeInfo }; | ||
} | ||
scope.vars[node.id.value] = input; | ||
return xnode; | ||
}, | ||
}, | ||
AssignmentStmt: { | ||
enter(node, visit) { | ||
const value = setOptional(node.optional, () => visit(node.value)); | ||
return trace.AssignmentStmt({ ...node, value }); | ||
}, | ||
}, | ||
IdentifierExpr(node) { | ||
@@ -69,13 +109,8 @@ const id = node.value.value; | ||
const xnode = trace.SliceExpr.enter(node, itemVisit(node, visit)); | ||
const typeInfo = { type: Type.Value }; | ||
let typeInfo = { type: Type.Value }; | ||
if (optional) | ||
typeInfo = { type: Type.Maybe, option: typeInfo }; | ||
return { ...xnode, typeInfo: rewrap(xnode.context?.typeInfo, typeInfo) }; | ||
}, | ||
}, | ||
ModuleCallExpr: { | ||
enter(node, visit) { | ||
const xnode = trace.ModuleCallExpr.enter(node, itemVisit(node, visit)); | ||
const typeInfo = { type: Type.Value }; | ||
return { ...xnode, typeInfo: rewrap(xnode.context?.typeInfo, typeInfo) }; | ||
}, | ||
}, | ||
SelectorExpr: { | ||
@@ -94,4 +129,8 @@ enter(node, visit) { | ||
} | ||
if (xnode.expand) | ||
if (xnode.expand) { | ||
typeInfo = { type: Type.List, of: typeInfo }; | ||
} | ||
else if (optional) { | ||
typeInfo = { type: Type.Maybe, option: typeInfo }; | ||
} | ||
return { ...xnode, typeInfo: rewrap(xnode.context?.typeInfo, typeInfo) }; | ||
@@ -126,3 +165,9 @@ }, | ||
enter(node, visit) { | ||
const xnode = trace.ObjectLiteralExpr.enter(node, itemVisit(node, visit)); | ||
const xnode = trace.ObjectLiteralExpr.enter(node, itemVisit(node, child => { | ||
if (child === node.context) | ||
return visit(child); | ||
const entry = node.entries.find(e => e.value === child); | ||
invariant(entry, new QuerySyntaxError('Object entry missing typeinfo')); | ||
return setOptional(entry.optional, () => visit(child)); | ||
})); | ||
const typeInfo = { | ||
@@ -140,4 +185,11 @@ type: Type.Struct, | ||
}, | ||
ModuleCallExpr: { | ||
enter(node, visit) { | ||
const xnode = trace.ModuleCallExpr.enter(node, itemVisit(node, visit)); | ||
const typeInfo = { type: Type.Value }; | ||
return { ...xnode, typeInfo: rewrap(xnode.context?.typeInfo, typeInfo) }; | ||
}, | ||
}, | ||
}; | ||
} | ||
//# sourceMappingURL=typeinfo.js.map |
@@ -65,4 +65,4 @@ import { invariant, QuerySyntaxError } from '@getlang/utils'; | ||
key: t.templateExpr([identifier]), | ||
optional: Boolean(optional), | ||
value, | ||
optional: Boolean(optional), | ||
}); | ||
@@ -69,0 +69,0 @@ export const objectEntryShorthandSelect = ([identifier, optional]) => { |
@@ -96,4 +96,4 @@ import { invariant, QuerySyntaxError } from '@getlang/utils' | ||
key: t.templateExpr([identifier]), | ||
optional: Boolean(optional), | ||
value, | ||
optional: Boolean(optional), | ||
}) | ||
@@ -100,0 +100,0 @@ |
{ | ||
"name": "@getlang/parser", | ||
"version": "0.0.24", | ||
"version": "0.0.25", | ||
"license": "Apache-2.0", | ||
@@ -42,3 +42,3 @@ "type": "module", | ||
"dependencies": { | ||
"@getlang/utils": "^0.0.14", | ||
"@getlang/utils": "^0.0.15", | ||
"@types/moo": "^0.5.9", | ||
@@ -45,0 +45,0 @@ "@types/nearley": "^2.11.5", |
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
214048
3977
+ Added@getlang/utils@0.0.15(transitive)
- Removed@getlang/utils@0.0.14(transitive)
Updated@getlang/utils@^0.0.15