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
|
use layout;
use core.lang;
use lang.bs;
optional delimiter = SDelimiter;
required delimiter = SRequiredDelimiter;
// Provide a new type definition keyword: 'window'.
// TODO: We might want to update this grammar to support decorators.
SClass => createFrame(pos, env, name, body) : "frame" #keyword ~ SName name #typeName, "{" - [SWindowBody@ body, ]+ "}";
SClass => createDialog(pos, env, name, body) : "dialog" #keyword ~ SName name #typeName, "{" - [SWindowBody@ body, ]+ "}";
SClass => createWindow(pos, env, name, body) : "window" #keyword ~ SName name #typeName, "{" - [SWindowBody@ body, ]+ "}";
SClass => createWindow(pos, env, name, parent, body) : "window" #keyword, SName name #typeName, "extends" #keyword, SType parent, "{" - [SWindowBody@ body, ]+ "}";
// Custom class body definition to include some more things!
ClassBody SWindowBody(Class owner);
SWindowBody => WindowBody(owner) : (SDocClassItem(owner) -> add)* - SDelimiter;
// The extra layout block only available inside 'window' declarations.
SWindowBody..SClassItem => WindowLayout(layout, true)
: "layout" #keyword ~ SWindowLayout layout;
SWindowBody..SClassItem => WindowLayout(layout, false)
: "layout" #keyword ~ "without" #keyword ~ "border" #keyword ~ SWindowLayout layout;
SLayoutRoot SWindowLayout();
SWindowLayout => layout : SLayoutRoot @layout;
// Allow type declarations in the layout.
SWindowLayout..SLayout => LayoutDeclBlock(block, name) : SType type, SName name #varName, ("(", SParamList(block.block) params, ")",)? "{" [, SLayoutContent(me),]+ "}" = SLayoutMemberDecl;
// Allow creating nested layouts for containers, for example to add groups and the like conveniently.
Expr SNestedContainer(Block block);
SNestedContainer => nestedContainerBlock(pos, block, layout, true)
: "container" #keyword ~ SLayout @layout;
SNestedContainer => nestedContainerBlock(pos, block, layout, false)
: "container" #keyword ~ "without" #keyword ~ "border" #keyword ~ SLayout @layout;
SWindowLayout..SAtom => x : SNestedContainer(block) x;
// Allow a property that ends with a nested layout without a trailing semicolon.
// Note: Ambiguous with pkg:type X {}, hence higher priority.
SWindowLayout..SLayoutItem[10] => addNested(block, name, params, last)
: SName name #varName - ":", (lang.bs.SExpr(block.block) params, ",", )* - SNestedContainer(block.block) last;
// Helper to manage layers in the Graphics object nicely.
SStmt => graphicsLayer(pos, block, g, params, contents) : "layer" #keyword, "(", SExpr(block) g, (",", SExpr(block) params,)* ")", SBlock(block) contents;
|