Improved field declaration parsing
This commit is contained in:
parent
71cde3daba
commit
ed12c1c69c
|
@ -87,16 +87,22 @@ export const spawn: Pattern<SpawnStatement> & { headerExpr: Pattern<Expr> } =
|
|||
});
|
||||
|
||||
export interface FieldDeclarationStatement extends FacetAction {
|
||||
member: Expr;
|
||||
expr?: Expr;
|
||||
target: Expr;
|
||||
property: { name: Identifier } | { expr: Expr };
|
||||
init?: Expr;
|
||||
}
|
||||
|
||||
// Principal: Dataspace, but only for implementation reasons, so really Facet
|
||||
export const fieldDeclarationStatement: Pattern<FieldDeclarationStatement> =
|
||||
facetAction(o => seq(atom('field'),
|
||||
bind(o, 'member', expr(atom('='))),
|
||||
option(seq(atom('='), bind(o, 'expr', expr()))),
|
||||
statementBoundary));
|
||||
facetAction(o => {
|
||||
const prop = alt(seq(atom('.'), map(identifier, name => o.property = {name})),
|
||||
seq(group('[', map(expr(), expr => o.property = {expr}))));
|
||||
return seq(atom('field'),
|
||||
bind(o, 'target', expr(seq(prop, alt(atom('='), statementBoundary)))),
|
||||
prop,
|
||||
option(seq(atom('='), bind(o, 'init', expr()))),
|
||||
statementBoundary);
|
||||
});
|
||||
|
||||
export interface AssertionEndpointStatement extends FacetAction {
|
||||
isDynamic: boolean,
|
||||
|
|
|
@ -51,29 +51,13 @@ export function main(argv: string[]) {
|
|||
expandFacetAction(
|
||||
G.fieldDeclarationStatement,
|
||||
s => {
|
||||
function isArrayProp(): [S.Substitution, S.Substitution] | null {
|
||||
if (s.member.length === 0) return null;
|
||||
const x = s.member[s.member.length - 1];
|
||||
if (!S.isGroup(x)) return null;
|
||||
if (x.start.text !== '[') return null;
|
||||
return [s.member.slice(0, s.member.length - 1), x.items];
|
||||
}
|
||||
function isSimpleProp(): [S.Substitution, S.Substitution] | null {
|
||||
if (s.member.length < 2) return null;
|
||||
const r = S.value<G.Identifier>(o => S.seq(S.atom('.'), S.bind(o, 'value', G.identifier)))(
|
||||
new ArrayList(s.member, s.member.length - 2));
|
||||
if (r === null) return null;
|
||||
const id = r[0];
|
||||
return [s.member.slice(0, s.member.length - 2),
|
||||
[ { start: id.start,
|
||||
end: id.end,
|
||||
type: S.TokenType.STRING,
|
||||
text: JSON.stringify(id.text) } ]];
|
||||
}
|
||||
const [obj, prop] = isArrayProp()
|
||||
?? isSimpleProp()
|
||||
?? ["__SYNDICATE__.INVALID_PROPERTY_SYNTAX", "''"];
|
||||
return macro.template()`declareField(${obj}, ${prop}, ${s.expr ?? 'void 0'});`;
|
||||
const prop = ('name' in s.property)
|
||||
? [ { start: s.property.name.start,
|
||||
end: s.property.name.end,
|
||||
type: S.TokenType.STRING,
|
||||
text: JSON.stringify(s.property.name.text) } ]
|
||||
: s.property.expr;
|
||||
return macro.template()`declareField(${s.target}, ${prop}, ${s.init ?? 'void 0'});`;
|
||||
});
|
||||
expandFacetAction(
|
||||
G.assertionEndpointStatement,
|
||||
|
|
|
@ -11,7 +11,8 @@ export type Pattern<T> = (i: List<Item>) => PatternResult<T>;
|
|||
export const noItems = new ArrayList<Item>([]);
|
||||
|
||||
export const fail: Pattern<never> = _i => null;
|
||||
export const succeed: Pattern<void> = i => [void 0, i];
|
||||
export function succeed<T>(t: T): Pattern<T> { return i => [t, i]; }
|
||||
|
||||
export const discard: Pattern<void> = _i => [void 0, noItems];
|
||||
export const rest: Pattern<Items> = i => [i.toArray(), noItems];
|
||||
export const end: Pattern<void> = i => atEnd(i) ? [void 0, noItems] : null;
|
||||
|
|
Loading…
Reference in New Issue