From 7cb653ab67d9bf8143fdad5a21a7e22c2b45a54d Mon Sep 17 00:00:00 2001 From: Olivier Date: Sun, 18 May 2025 14:42:48 +0100 Subject: [PATCH] Add optional parameter declarations (including default values) --- hornbeam_grammar/src/ast.rs | 8 ++ hornbeam_grammar/src/hornbeam.pest | 25 +++- hornbeam_grammar/src/parser.rs | 68 ++++++++- ...am_grammar__parser__tests__for_blocks.snap | 2 +- ...r__parser__tests__fragments_and_slots.snap | 2 +- ...m_grammar__parser__tests__if_blocks-2.snap | 2 +- ...eam_grammar__parser__tests__if_blocks.snap | 2 +- ..._grammar__parser__tests__localisation.snap | 2 +- ..._grammar__parser__tests__match_blocks.snap | 2 +- ...am_grammar__parser__tests__param_defs.snap | 18 +++ .../hornbeam_grammar__parser__tests__raw.snap | 2 +- ..._parser__tests__simple_parses_correct.snap | 2 +- ...__tests__string_interpolations_nested.snap | 2 +- ...ts__supply_slots_to_components_only-2.snap | 2 +- hornbeam_interpreter/src/engine.rs | 101 +++++++++++++- hornbeam_interpreter/tests/snapshots.rs | 16 +++ .../snapshots/snapshots__snapshot_006.snap | 5 + hornbeam_ir/src/ast_to_ir.rs | 58 +++++--- hornbeam_ir/src/ir.rs | 1 + ..._ir__ast_to_ir__tests__compile_params.snap | 85 ++++++++++++ ...st_to_ir__tests__pull_out_entrypoints.snap | 129 +++++++++--------- 21 files changed, 440 insertions(+), 94 deletions(-) create mode 100644 hornbeam_grammar/src/snapshots/hornbeam_grammar__parser__tests__param_defs.snap create mode 100644 hornbeam_interpreter/tests/snapshots/snapshots__snapshot_006.snap create mode 100644 hornbeam_ir/src/snapshots/hornbeam_ir__ast_to_ir__tests__compile_params.snap 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