From 9598e4ff43a8fd4bc2aa2af75ff1094c2ef96258 Mon Sep 17 00:00:00 2001 From: NanoTech Date: Wed, 7 Dec 2016 18:11:05 -0600 Subject: Reference input strings without copying --- src/core.rs | 61 +++++++++++++++++++++++++++-------------------------- src/grammar.lalrpop | 49 +++++++++++++++++++++--------------------- src/grammar_util.rs | 10 ++++----- src/lexer.rs | 14 ++++++------ src/parser.rs | 2 +- 5 files changed, 70 insertions(+), 66 deletions(-) (limited to 'src') diff --git a/src/core.rs b/src/core.rs index 8e59141..85ebf1b 100644 --- a/src/core.rs +++ b/src/core.rs @@ -1,3 +1,4 @@ +use std::borrow::Cow; use std::collections::HashMap; use std::path::PathBuf; @@ -43,7 +44,7 @@ module Dhall.Core ( /// Note that Dhall does not support functions from terms to types and therefore /// Dhall is not a dependently typed language /// -#[derive(Debug, PartialEq, Eq)] // (Show, Bounded, Enum) +#[derive(Debug, Copy, Clone, PartialEq, Eq)] // (Show, Bounded, Enum) pub enum Const { Type, Kind, @@ -51,7 +52,7 @@ pub enum Const { /// Path to an external resource -#[derive(Debug, PartialEq, Eq)] // (Eq, Ord, Show) +#[derive(Debug, Clone, PartialEq, Eq)] // (Eq, Ord, Show) pub enum Path { File(PathBuf), URL(String), @@ -93,8 +94,8 @@ pub enum Path { /// Zero indices are omitted when pretty-printing `Var`s and non-zero indices /// appear as a numeric suffix. /// -#[derive(Debug, PartialEq, Eq)] // (Eq, Show) -pub struct Var(pub String, pub Int); +#[derive(Debug, Clone, PartialEq, Eq)] // (Eq, Show) +pub struct V<'i>(pub Cow<'i, str>, pub usize); /* instance IsString Var where @@ -105,39 +106,39 @@ instance Buildable Var where */ /// Syntax tree for expressions -#[derive(Debug, PartialEq)] // (Functor, Foldable, Traversable, Show) -pub enum Expr { +#[derive(Debug, Clone, PartialEq)] // (Functor, Foldable, Traversable, Show) +pub enum Expr<'i, S, A> { /// `Const c ~ c` Const(Const), /// `Var (V x 0) ~ x`
/// `Var (V x n) ~ x@n` - Var(Var), + Var(V<'i>), /// `Lam x A b ~ λ(x : A) -> b` - Lam(String, Box>, Box>), + Lam(Cow<'i, str>, Box>, Box>), /// `Pi "_" A B ~ A -> B` /// `Pi x A B ~ ∀(x : A) -> B` - Pi(String, Box>, Box>), + Pi(Cow<'i, str>, Box>, Box>), /// `App f A ~ f A` - App(Box>, Box>), + App(Box>, Box>), /// `Let x Nothing r e ~ let x = r in e` /// `Let x (Just t) r e ~ let x : t = r in e` - Let(String, Option>>, Box>, Box>), + Let(Cow<'i, str>, Option>>, Box>, Box>), /// `Annot x t ~ x : t` - Annot(Box>, Box>), + Annot(Box>, Box>), /// `Bool ~ Bool` Bool, /// `BoolLit b ~ b` BoolLit(bool), /// `BoolAnd x y ~ x && y` - BoolAnd(Box>, Box>), + BoolAnd(Box>, Box>), /// `BoolOr x y ~ x || y` - BoolOr(Box>, Box>), + BoolOr(Box>, Box>), /// `BoolEQ x y ~ x == y` - BoolEQ(Box>, Box>), + BoolEQ(Box>, Box>), /// `BoolNE x y ~ x != y` - BoolNE(Box>, Box>), + BoolNE(Box>, Box>), /// `BoolIf x y z ~ if x then y else z` - BoolIf(Box>, Box>, Box>), + BoolIf(Box>, Box>, Box>), /// `Natural ~ Natural` Natural, /// `NaturalLit n ~ +n` @@ -153,9 +154,9 @@ pub enum Expr { /// `NaturalOdd ~ Natural/odd` NaturalOdd, /// `NaturalPlus x y ~ x + y` - NaturalPlus(Box>, Box>), + NaturalPlus(Box>, Box>), /// `NaturalTimes x y ~ x * y` - NaturalTimes(Box>, Box>), + NaturalTimes(Box>, Box>), /// `Integer ~ Integer` Integer, /// `IntegerLit n ~ n` @@ -169,11 +170,11 @@ pub enum Expr { /// `TextLit t ~ t` TextLit(Builder), /// `TextAppend x y ~ x ++ y` - TextAppend(Box>, Box>), + TextAppend(Box>, Box>), /// `List ~ List` List, /// `ListLit t [x, y, z] ~ [x, y, z] : List t` - ListLit(Box>, Vec>), + ListLit(Box>, Vec>), /// `ListBuild ~ List/build` ListBuild, /// `ListFold ~ List/fold` @@ -192,25 +193,25 @@ pub enum Expr { Optional, /// `OptionalLit t [e] ~ [e] : Optional t` /// `OptionalLit t [] ~ [] : Optional t` - OptionalLit(Box>, Vec>), + OptionalLit(Box>, Vec>), /// `OptionalFold ~ Optional/fold` OptionalFold, /// `Record [(k1, t1), (k2, t2)] ~ { k1 : t1, k2 : t1 }` - Record(HashMap>), + Record(HashMap, Expr<'i, S, A>>), /// `RecordLit [(k1, v1), (k2, v2)] ~ { k1 = v1, k2 = v2 }` - RecordLit(HashMap>), + RecordLit(HashMap, Expr<'i, S, A>>), /// `Union [(k1, t1), (k2, t2)] ~ < k1 : t1, k2 : t2 >` - Union(HashMap>), + Union(HashMap, Expr<'i, S, A>>), /// `UnionLit (k1, v1) [(k2, t2), (k3, t3)] ~ < k1 = t1, k2 : t2, k3 : t3 >` - UnionLit(String, Box>, HashMap>), + UnionLit(Cow<'i, str>, Box>, HashMap, Expr<'i, S, A>>), /// `Combine x y ~ x ∧ y` - Combine(Box>, Box>), + Combine(Box>, Box>), /// `Merge x y t ~ merge x y : t` - Merge(Box>, Box>, Box>), + Merge(Box>, Box>, Box>), /// `Field e x ~ e.x` - Field(Box>, String), + Field(Box>, Cow<'i, str>), /// `Note S x ~ e` - Note(S, Box>), + Note(S, Box>), /// `Embed path ~ path` Embed(A), } diff --git a/src/grammar.lalrpop b/src/grammar.lalrpop index c49e2b6..3e216ac 100644 --- a/src/grammar.lalrpop +++ b/src/grammar.lalrpop @@ -3,17 +3,18 @@ use core::Expr::*; use grammar_util::*; use lexer::*; +use std::borrow::Cow; use std::collections::HashMap; use std::iter; use std::iter::FromIterator; -grammar; +grammar<'input>; extern { type Location = usize; type Error = LexicalError; - enum Tok { + enum Tok<'input> { Pi => Tok::Pi, Lambda => Tok::Lambda, Combine => Tok::Combine, @@ -23,7 +24,7 @@ extern { Nat => Tok::Natural(), Text => Tok::Text(), Bool => Tok::Bool(), - Label => Tok::Identifier(), + Label => Tok::Identifier(>), Const => Tok::Const(), Let => Tok::Keyword(Keyword::Let), In => Tok::Keyword(Keyword::In), @@ -54,36 +55,36 @@ extern { } } -pub Expr: BoxExpr = { // exprA +pub Expr: BoxExpr<'input> = { // exprA ":" => bx(Annot(<>)), ExprB, }; -ExprB: BoxExpr = { +ExprB: BoxExpr<'input> = { Lambda "("