diff --git a/hornbeam_grammar/src/ast.rs b/hornbeam_grammar/src/ast.rs index e1f44a3..495f177 100644 --- a/hornbeam_grammar/src/ast.rs +++ b/hornbeam_grammar/src/ast.rs @@ -4,9 +4,17 @@ use std::collections::BTreeMap; #[derive(Clone, Debug, Eq, PartialEq, Serialize)] pub struct Template { + pub param_defs: Option>, pub blocks: Vec, } +#[derive(Clone, Debug, Eq, PartialEq, Serialize)] +pub struct ParameterDefinition { + pub name: IStr, + pub loc: Locator, + pub default: Option, +} + #[derive(Clone, Debug, Eq, PartialEq, Serialize)] pub enum Block { HtmlElement(HtmlElement), diff --git a/hornbeam_grammar/src/hornbeam.pest b/hornbeam_grammar/src/hornbeam.pest index 4d03351..e0b8a7e 100644 --- a/hornbeam_grammar/src/hornbeam.pest +++ b/hornbeam_grammar/src/hornbeam.pest @@ -1,5 +1,21 @@ // -Hornbeam = { SOI ~ wsnl* ~ BlockContent* ~ ws* ~ EOI } +Hornbeam = { SOI ~ wsnl* ~ PreambleList? ~ wsnl* ~ HornbeamBlockList ~ ws* ~ EOI } + +// Will eventually expand to other types of preamble content +PreambleList = { + // accept `declare` keyword. We expect `PEEK_ALL` to be empty, but future definitions might change this. + PEEK_ALL ~ "declare" ~ lineEnd ~ + // then accept the first definition. We must have at least one definition. + // We accept the new indentation level with the `PUSH` here + PEEK_ALL ~ PUSH(" "+ | "\t"+) ~ ParameterDefinition ~ + // Now accept any number of extra definitions at the same indentation level. + (PEEK_ALL ~ ParameterDefinition)* ~ + // Drop the indentation when exiting the preamble block + DROP +} + + +HornbeamBlockList = { BlockContent* } NewBlock = _{ PEEK_ALL ~ PUSH(" "+ | "\t"+) ~ BlockContent ~ @@ -18,6 +34,13 @@ BlockContent = _{ DefineFragment } +// `param $x` +// `param $x = 1 + 1` +// TODO: type annotation: `param $x: int` +ParameterDefinition = { + "param" ~ ws+ ~ "$" ~ Identifier ~ (ws* ~ "=" ~ ws* ~ Expr)? ~ lineEnd +} + Element = { ElementName ~ cssClass* ~ domId? ~ (ws+ ~ AttrMapLiteral)? ~ lineEnd ~ (NewBlock | NewSlotBlock)? } diff --git a/hornbeam_grammar/src/parser.rs b/hornbeam_grammar/src/parser.rs index f7f4fb5..4422db3 100644 --- a/hornbeam_grammar/src/parser.rs +++ b/hornbeam_grammar/src/parser.rs @@ -2,8 +2,8 @@ use crate::ast::{ Binding, Block, ComponentElement, DefineExpandSlot, DefineFragment, ElementAttributeFlags, - Expression, ForBlock, HtmlElement, IfBlock, MatchBinding, MatchBlock, SetStatement, StringExpr, - StringPiece, Template, + Expression, ForBlock, HtmlElement, IfBlock, MatchBinding, MatchBlock, ParameterDefinition, + SetStatement, StringExpr, StringPiece, Template, }; use crate::{intern, IStr, Locator}; use lazy_static::lazy_static; @@ -61,8 +61,51 @@ lazy_static! { #[pest_consume::parser] impl HornbeamParser { fn Hornbeam(input: Node) -> PCResult