feat: parse imports
This commit is contained in:
parent
1d6809661c
commit
1d1a6fc404
|
@ -10,23 +10,26 @@ use crate::{
|
||||||
pub type TypedModule = Module<tipo::Module, TypedDefinition>;
|
pub type TypedModule = Module<tipo::Module, TypedDefinition>;
|
||||||
pub type UntypedModule = Module<(), UntypedDefinition>;
|
pub type UntypedModule = Module<(), UntypedDefinition>;
|
||||||
|
|
||||||
|
#[derive(Debug, Copy, Clone, PartialEq, Eq)]
|
||||||
pub enum ModuleKind {
|
pub enum ModuleKind {
|
||||||
Contract,
|
Contract,
|
||||||
Lib,
|
Lib,
|
||||||
Script,
|
Script,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[derive(Debug, Clone, PartialEq, Eq)]
|
||||||
pub struct Module<Info, Definitions> {
|
pub struct Module<Info, Definitions> {
|
||||||
pub name: Vec<String>,
|
pub name: Vec<String>,
|
||||||
pub docs: Vec<String>,
|
pub docs: Vec<String>,
|
||||||
pub type_info: Info,
|
pub type_info: Info,
|
||||||
pub definitons: Vec<Definitions>,
|
pub definitions: Vec<Definitions>,
|
||||||
pub kind: ModuleKind,
|
pub kind: ModuleKind,
|
||||||
}
|
}
|
||||||
|
|
||||||
pub type TypedDefinition = Definition<Arc<Type>, TypedExpr, String, String>;
|
pub type TypedDefinition = Definition<Arc<Type>, TypedExpr, String, String>;
|
||||||
pub type UntypedDefinition = Definition<(), UntypedExpr, (), ()>;
|
pub type UntypedDefinition = Definition<(), UntypedExpr, (), ()>;
|
||||||
|
|
||||||
|
#[derive(Debug, Clone, PartialEq)]
|
||||||
pub enum Definition<T, Expr, ConstantRecordTag, PackageName> {
|
pub enum Definition<T, Expr, ConstantRecordTag, PackageName> {
|
||||||
Fn {
|
Fn {
|
||||||
location: Span,
|
location: Span,
|
||||||
|
@ -61,6 +64,7 @@ pub enum Definition<T, Expr, ConstantRecordTag, PackageName> {
|
||||||
},
|
},
|
||||||
|
|
||||||
Use {
|
Use {
|
||||||
|
location: Span,
|
||||||
module: Vec<String>,
|
module: Vec<String>,
|
||||||
as_name: Option<String>,
|
as_name: Option<String>,
|
||||||
unqualified: Vec<UnqualifiedImport>,
|
unqualified: Vec<UnqualifiedImport>,
|
||||||
|
@ -81,6 +85,7 @@ pub enum Definition<T, Expr, ConstantRecordTag, PackageName> {
|
||||||
pub type TypedConstant = Constant<Arc<Type>, String>;
|
pub type TypedConstant = Constant<Arc<Type>, String>;
|
||||||
pub type UntypedConstant = Constant<(), ()>;
|
pub type UntypedConstant = Constant<(), ()>;
|
||||||
|
|
||||||
|
#[derive(Debug, Clone, PartialEq)]
|
||||||
pub enum Constant<T, RecordTag> {
|
pub enum Constant<T, RecordTag> {
|
||||||
Int {
|
Int {
|
||||||
location: Span,
|
location: Span,
|
||||||
|
@ -127,17 +132,20 @@ pub enum Constant<T, RecordTag> {
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[derive(Debug, Clone, PartialEq, Eq)]
|
||||||
pub struct CallArg<A> {
|
pub struct CallArg<A> {
|
||||||
pub label: Option<String>,
|
pub label: Option<String>,
|
||||||
pub location: Span,
|
pub location: Span,
|
||||||
pub value: A,
|
pub value: A,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[derive(Debug, Clone, PartialEq, Eq)]
|
||||||
pub struct FieldMap {
|
pub struct FieldMap {
|
||||||
pub arity: usize,
|
pub arity: usize,
|
||||||
pub fields: HashMap<String, usize>,
|
pub fields: HashMap<String, usize>,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[derive(Debug, Clone, PartialEq)]
|
||||||
pub struct RecordConstructor<T> {
|
pub struct RecordConstructor<T> {
|
||||||
pub location: Span,
|
pub location: Span,
|
||||||
pub name: String,
|
pub name: String,
|
||||||
|
@ -145,6 +153,7 @@ pub struct RecordConstructor<T> {
|
||||||
pub documentation: Option<String>,
|
pub documentation: Option<String>,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[derive(Debug, Clone, PartialEq)]
|
||||||
pub struct RecordConstructorArg<T> {
|
pub struct RecordConstructorArg<T> {
|
||||||
pub label: Option<String>,
|
pub label: Option<String>,
|
||||||
// ast
|
// ast
|
||||||
|
@ -154,6 +163,7 @@ pub struct RecordConstructorArg<T> {
|
||||||
pub doc: Option<String>,
|
pub doc: Option<String>,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[derive(Debug, Clone, PartialEq)]
|
||||||
pub struct Arg<T> {
|
pub struct Arg<T> {
|
||||||
pub names: ArgName,
|
pub names: ArgName,
|
||||||
pub location: Span,
|
pub location: Span,
|
||||||
|
@ -161,6 +171,7 @@ pub struct Arg<T> {
|
||||||
pub tipo: T,
|
pub tipo: T,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[derive(Debug, Clone, PartialEq, Eq)]
|
||||||
pub enum ArgName {
|
pub enum ArgName {
|
||||||
Discard { name: String },
|
Discard { name: String },
|
||||||
LabeledDiscard { label: String, name: String },
|
LabeledDiscard { label: String, name: String },
|
||||||
|
@ -168,6 +179,7 @@ pub enum ArgName {
|
||||||
NamedLabeled { name: String, label: String },
|
NamedLabeled { name: String, label: String },
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[derive(Debug, Clone, PartialEq, Eq)]
|
||||||
pub struct UnqualifiedImport {
|
pub struct UnqualifiedImport {
|
||||||
pub location: Span,
|
pub location: Span,
|
||||||
pub name: String,
|
pub name: String,
|
||||||
|
@ -176,6 +188,7 @@ pub struct UnqualifiedImport {
|
||||||
}
|
}
|
||||||
|
|
||||||
// TypeAst
|
// TypeAst
|
||||||
|
#[derive(Debug, Clone, PartialEq)]
|
||||||
pub enum Annotation {
|
pub enum Annotation {
|
||||||
Constructor {
|
Constructor {
|
||||||
location: Span,
|
location: Span,
|
||||||
|
@ -206,6 +219,7 @@ pub enum Annotation {
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[derive(Debug, Clone, PartialEq, Eq)]
|
||||||
pub enum Layer {
|
pub enum Layer {
|
||||||
Value,
|
Value,
|
||||||
Type,
|
Type,
|
||||||
|
@ -217,6 +231,7 @@ impl Default for Layer {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[derive(Debug, Clone, PartialEq, Eq)]
|
||||||
pub enum BinOp {
|
pub enum BinOp {
|
||||||
// Boolean logic
|
// Boolean logic
|
||||||
And,
|
And,
|
||||||
|
@ -240,6 +255,7 @@ pub enum BinOp {
|
||||||
ModInt,
|
ModInt,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[derive(Debug, Clone, PartialEq)]
|
||||||
pub enum Pattern<Constructor, Type> {
|
pub enum Pattern<Constructor, Type> {
|
||||||
Int {
|
Int {
|
||||||
location: Span,
|
location: Span,
|
||||||
|
@ -309,6 +325,7 @@ pub enum Pattern<Constructor, Type> {
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[derive(Debug, Clone, PartialEq, Eq)]
|
||||||
pub enum AssignmentKind {
|
pub enum AssignmentKind {
|
||||||
Let,
|
Let,
|
||||||
Assert,
|
Assert,
|
||||||
|
@ -323,6 +340,7 @@ pub type TypedClause = Clause<TypedExpr, PatternConstructor, Arc<Type>, String>;
|
||||||
|
|
||||||
pub type UntypedClause = Clause<UntypedExpr, (), (), ()>;
|
pub type UntypedClause = Clause<UntypedExpr, (), (), ()>;
|
||||||
|
|
||||||
|
#[derive(Debug, Clone, PartialEq)]
|
||||||
pub struct Clause<Expr, PatternConstructor, Type, RecordTag> {
|
pub struct Clause<Expr, PatternConstructor, Type, RecordTag> {
|
||||||
pub location: Span,
|
pub location: Span,
|
||||||
pub pattern: MultiPattern<PatternConstructor, Type>,
|
pub pattern: MultiPattern<PatternConstructor, Type>,
|
||||||
|
@ -331,6 +349,7 @@ pub struct Clause<Expr, PatternConstructor, Type, RecordTag> {
|
||||||
pub then: Expr,
|
pub then: Expr,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[derive(Debug, Clone, PartialEq)]
|
||||||
pub enum ClauseGuard<Type, RecordTag> {
|
pub enum ClauseGuard<Type, RecordTag> {
|
||||||
Equals {
|
Equals {
|
||||||
location: Span,
|
location: Span,
|
||||||
|
@ -403,17 +422,20 @@ pub struct TypedRecordUpdateArg {
|
||||||
pub index: usize,
|
pub index: usize,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[derive(Debug, Clone, PartialEq)]
|
||||||
pub struct UntypedRecordUpdateArg {
|
pub struct UntypedRecordUpdateArg {
|
||||||
pub label: String,
|
pub label: String,
|
||||||
// pub location: SrcSpan,
|
// pub location: SrcSpan,
|
||||||
pub value: UntypedExpr,
|
pub value: UntypedExpr,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[derive(Debug, Clone, PartialEq)]
|
||||||
pub struct RecordUpdateSpread {
|
pub struct RecordUpdateSpread {
|
||||||
pub base: Box<UntypedExpr>,
|
pub base: Box<UntypedExpr>,
|
||||||
pub location: Span,
|
pub location: Span,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[derive(Debug, Clone, PartialEq, Eq)]
|
||||||
pub enum TodoKind {
|
pub enum TodoKind {
|
||||||
Keyword,
|
Keyword,
|
||||||
EmptyFunction,
|
EmptyFunction,
|
||||||
|
|
|
@ -153,6 +153,7 @@ pub enum TypedExpr {
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[derive(Debug, Clone, PartialEq)]
|
||||||
pub enum UntypedExpr {
|
pub enum UntypedExpr {
|
||||||
Int {
|
Int {
|
||||||
location: Span,
|
location: Span,
|
||||||
|
|
|
@ -26,6 +26,7 @@ pub fn lexer() -> impl Parser<char, Vec<(Token, Span)>, Error = ParseError> {
|
||||||
just('/').to(Token::Slash),
|
just('/').to(Token::Slash),
|
||||||
just('%').to(Token::Percent),
|
just('%').to(Token::Percent),
|
||||||
just("|>").to(Token::Pipe),
|
just("|>").to(Token::Pipe),
|
||||||
|
just(',').to(Token::Comma),
|
||||||
));
|
));
|
||||||
|
|
||||||
let grouping = choice((
|
let grouping = choice((
|
||||||
|
@ -75,7 +76,7 @@ pub fn lexer() -> impl Parser<char, Vec<(Token, Span)>, Error = ParseError> {
|
||||||
if s.chars().next().map_or(false, |c| c.is_uppercase()) {
|
if s.chars().next().map_or(false, |c| c.is_uppercase()) {
|
||||||
Token::UpName {
|
Token::UpName {
|
||||||
// TODO: do not allow _ in upname
|
// TODO: do not allow _ in upname
|
||||||
name: Intern::new(s),
|
name: s,
|
||||||
}
|
}
|
||||||
} else if s.starts_with('_') {
|
} else if s.starts_with('_') {
|
||||||
Token::DiscardName {
|
Token::DiscardName {
|
||||||
|
@ -85,7 +86,7 @@ pub fn lexer() -> impl Parser<char, Vec<(Token, Span)>, Error = ParseError> {
|
||||||
} else {
|
} else {
|
||||||
Token::Name {
|
Token::Name {
|
||||||
// TODO: do not allow uppercase letters in name
|
// TODO: do not allow uppercase letters in name
|
||||||
name: Intern::new(s),
|
name: s,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -93,7 +94,11 @@ pub fn lexer() -> impl Parser<char, Vec<(Token, Span)>, Error = ParseError> {
|
||||||
|
|
||||||
let token = choice((keyword, int, op, grouping, string))
|
let token = choice((keyword, int, op, grouping, string))
|
||||||
.or(any().map(Token::Error).validate(|t, span, emit| {
|
.or(any().map(Token::Error).validate(|t, span, emit| {
|
||||||
emit(ParseError::expected_input_found(span, None, Some(t)));
|
emit(ParseError::expected_input_found(
|
||||||
|
span,
|
||||||
|
None,
|
||||||
|
Some(t.clone()),
|
||||||
|
));
|
||||||
t
|
t
|
||||||
}))
|
}))
|
||||||
.map_with_span(move |token, span| (token, span))
|
.map_with_span(move |token, span| (token, span))
|
||||||
|
@ -149,13 +154,13 @@ mod tests {
|
||||||
Token::GreaterEqual,
|
Token::GreaterEqual,
|
||||||
Token::LeftBrace,
|
Token::LeftBrace,
|
||||||
Token::UpName {
|
Token::UpName {
|
||||||
name: Intern::new("Thing".to_string())
|
name: "Thing".to_string()
|
||||||
},
|
},
|
||||||
Token::DiscardName {
|
Token::DiscardName {
|
||||||
name: Intern::new("_na_thing".to_string())
|
name: Intern::new("_na_thing".to_string())
|
||||||
},
|
},
|
||||||
Token::Name {
|
Token::Name {
|
||||||
name: Intern::new("name".to_string())
|
name: "name".to_string()
|
||||||
}
|
}
|
||||||
]),
|
]),
|
||||||
);
|
);
|
||||||
|
|
|
@ -2,6 +2,147 @@ use chumsky::prelude::*;
|
||||||
|
|
||||||
use crate::{ast, error::ParseError, token::Token};
|
use crate::{ast, error::ParseError, token::Token};
|
||||||
|
|
||||||
pub fn module_parser() -> impl Parser<Token, ast::UntypedModule, Error = ParseError> {
|
pub fn module_parser(
|
||||||
let imports = just(Token::Use).ignore_then();
|
kind: ast::ModuleKind,
|
||||||
|
) -> impl Parser<Token, ast::UntypedModule, Error = ParseError> {
|
||||||
|
let unqualified_import = choice((
|
||||||
|
select! {Token::Name { name } => name}.then(
|
||||||
|
just(Token::As)
|
||||||
|
.ignore_then(select! {Token::Name { name } => name})
|
||||||
|
.or_not(),
|
||||||
|
),
|
||||||
|
select! {Token::UpName { name } => name}.then(
|
||||||
|
just(Token::As)
|
||||||
|
.ignore_then(select! {Token::UpName { name } => name})
|
||||||
|
.or_not(),
|
||||||
|
),
|
||||||
|
))
|
||||||
|
.map_with_span(|(name, as_name), span| ast::UnqualifiedImport {
|
||||||
|
name,
|
||||||
|
location: span,
|
||||||
|
as_name,
|
||||||
|
layer: Default::default(),
|
||||||
|
});
|
||||||
|
|
||||||
|
let unqualified_imports = just(Token::Dot)
|
||||||
|
.ignore_then(
|
||||||
|
unqualified_import
|
||||||
|
.separated_by(just(Token::Comma))
|
||||||
|
.delimited_by(just(Token::LeftBrace), just(Token::RightBrace)),
|
||||||
|
)
|
||||||
|
.or_not();
|
||||||
|
|
||||||
|
let as_name = just(Token::As)
|
||||||
|
.ignore_then(select! {Token::Name { name } => name})
|
||||||
|
.or_not();
|
||||||
|
|
||||||
|
let module_path = select! {Token::Name { name } => name}
|
||||||
|
.separated_by(just(Token::Slash))
|
||||||
|
.then(unqualified_imports)
|
||||||
|
.then(as_name);
|
||||||
|
|
||||||
|
let import = just(Token::Use).ignore_then(module_path).map_with_span(
|
||||||
|
|((module, unqualified), as_name), span| ast::UntypedDefinition::Use {
|
||||||
|
module,
|
||||||
|
as_name,
|
||||||
|
unqualified: unqualified.unwrap_or_default(),
|
||||||
|
package: (),
|
||||||
|
location: span,
|
||||||
|
},
|
||||||
|
);
|
||||||
|
|
||||||
|
choice((import,))
|
||||||
|
.repeated()
|
||||||
|
.then_ignore(end())
|
||||||
|
.map(move |definitions| ast::UntypedModule {
|
||||||
|
kind,
|
||||||
|
definitions,
|
||||||
|
docs: vec![],
|
||||||
|
name: vec![],
|
||||||
|
type_info: (),
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
#[cfg(test)]
|
||||||
|
mod tests {
|
||||||
|
use chumsky::prelude::*;
|
||||||
|
|
||||||
|
use crate::{
|
||||||
|
ast::{self, Span, SrcId},
|
||||||
|
lexer,
|
||||||
|
parser::module_parser,
|
||||||
|
};
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn simple() {
|
||||||
|
let code = r#"
|
||||||
|
use std/list
|
||||||
|
use std/address.{Address as A, thing as w}
|
||||||
|
use std/tx as t
|
||||||
|
"#;
|
||||||
|
let len = code.chars().count();
|
||||||
|
|
||||||
|
let span = |i| Span::new(SrcId::empty(), i..i + 1);
|
||||||
|
|
||||||
|
let tokens = lexer::lexer()
|
||||||
|
.parse(chumsky::Stream::from_iter(
|
||||||
|
span(len),
|
||||||
|
code.chars().enumerate().map(|(i, c)| (c, span(i))),
|
||||||
|
))
|
||||||
|
.unwrap();
|
||||||
|
|
||||||
|
dbg!(tokens.clone());
|
||||||
|
|
||||||
|
let res = module_parser(ast::ModuleKind::Script)
|
||||||
|
.parse(chumsky::Stream::from_iter(span(len), tokens.into_iter()))
|
||||||
|
.unwrap();
|
||||||
|
|
||||||
|
assert_eq!(
|
||||||
|
res,
|
||||||
|
ast::UntypedModule {
|
||||||
|
docs: vec![],
|
||||||
|
kind: ast::ModuleKind::Script,
|
||||||
|
name: vec![],
|
||||||
|
type_info: (),
|
||||||
|
definitions: vec![
|
||||||
|
ast::UntypedDefinition::Use {
|
||||||
|
location: Span::new(SrcId::empty(), 13..25),
|
||||||
|
module: vec!["std".to_string(), "list".to_string()],
|
||||||
|
as_name: None,
|
||||||
|
unqualified: vec![],
|
||||||
|
package: (),
|
||||||
|
},
|
||||||
|
ast::UntypedDefinition::Use {
|
||||||
|
location: Span::new(SrcId::empty(), 38..80),
|
||||||
|
module: vec!["std".to_string(), "address".to_string()],
|
||||||
|
as_name: None,
|
||||||
|
unqualified: vec![
|
||||||
|
ast::UnqualifiedImport {
|
||||||
|
as_name: Some("A".to_string()),
|
||||||
|
location: Span::new(SrcId::empty(), 55..67),
|
||||||
|
layer: Default::default(),
|
||||||
|
name: "Address".to_string()
|
||||||
|
},
|
||||||
|
ast::UnqualifiedImport {
|
||||||
|
as_name: Some("w".to_string()),
|
||||||
|
location: Span::new(SrcId::empty(), 69..79),
|
||||||
|
layer: Default::default(),
|
||||||
|
name: "thing".to_string()
|
||||||
|
}
|
||||||
|
],
|
||||||
|
package: (),
|
||||||
|
},
|
||||||
|
ast::UntypedDefinition::Use {
|
||||||
|
location: Span::new(SrcId::empty(), 93..108),
|
||||||
|
module: vec!["std".to_string(), "tx".to_string()],
|
||||||
|
as_name: Some("t".to_string()),
|
||||||
|
unqualified: vec![],
|
||||||
|
package: (),
|
||||||
|
}
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"{:#?}",
|
||||||
|
res,
|
||||||
|
);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -5,6 +5,7 @@ use crate::{
|
||||||
build::Origin,
|
build::Origin,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
#[derive(Debug, Clone, PartialEq)]
|
||||||
pub enum Type {
|
pub enum Type {
|
||||||
/// A nominal (named) type such as `Int`, `Float`, or a programmer defined
|
/// A nominal (named) type such as `Int`, `Float`, or a programmer defined
|
||||||
/// custom type such as `Person`. The type can take other types as
|
/// custom type such as `Person`. The type can take other types as
|
||||||
|
@ -39,6 +40,7 @@ pub enum Type {
|
||||||
Tuple { elems: Vec<Arc<Type>> },
|
Tuple { elems: Vec<Arc<Type>> },
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[derive(Debug, Clone, PartialEq)]
|
||||||
pub enum TypeVar {
|
pub enum TypeVar {
|
||||||
/// Unbound is an unbound variable. It is one specific type but we don't
|
/// Unbound is an unbound variable. It is one specific type but we don't
|
||||||
/// know what yet in the inference process. It has a unique id which can be used to
|
/// know what yet in the inference process. It has a unique id which can be used to
|
||||||
|
@ -65,12 +67,14 @@ pub enum TypeVar {
|
||||||
Generic { id: u64 },
|
Generic { id: u64 },
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[derive(Debug, Clone, PartialEq)]
|
||||||
pub struct ValueConstructor {
|
pub struct ValueConstructor {
|
||||||
pub public: bool,
|
pub public: bool,
|
||||||
pub variant: ValueConstructorVariant,
|
pub variant: ValueConstructorVariant,
|
||||||
pub tipo: Arc<Type>,
|
pub tipo: Arc<Type>,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[derive(Debug, Clone, PartialEq)]
|
||||||
pub enum ValueConstructorVariant {
|
pub enum ValueConstructorVariant {
|
||||||
/// A locally defined variable or function parameter
|
/// A locally defined variable or function parameter
|
||||||
LocalVariable { location: Span },
|
LocalVariable { location: Span },
|
||||||
|
|
|
@ -2,11 +2,11 @@ use std::fmt;
|
||||||
|
|
||||||
use internment::Intern;
|
use internment::Intern;
|
||||||
|
|
||||||
#[derive(Copy, Clone, Debug, PartialEq, Hash, Eq)]
|
#[derive(Clone, Debug, PartialEq, Hash, Eq)]
|
||||||
pub enum Token {
|
pub enum Token {
|
||||||
Error(char),
|
Error(char),
|
||||||
Name { name: Intern<String> },
|
Name { name: String },
|
||||||
UpName { name: Intern<String> },
|
UpName { name: String },
|
||||||
DiscardName { name: Intern<String> },
|
DiscardName { name: Intern<String> },
|
||||||
Int { value: Intern<String> },
|
Int { value: Intern<String> },
|
||||||
String { value: Intern<String> },
|
String { value: Intern<String> },
|
||||||
|
@ -82,8 +82,8 @@ impl fmt::Display for Token {
|
||||||
|
|
||||||
return Ok(());
|
return Ok(());
|
||||||
}
|
}
|
||||||
Token::Name { name } => &**name,
|
Token::Name { name } => name,
|
||||||
Token::UpName { name } => &**name,
|
Token::UpName { name } => name,
|
||||||
Token::DiscardName { name } => &**name,
|
Token::DiscardName { name } => &**name,
|
||||||
Token::Int { value } => &**value,
|
Token::Int { value } => &**value,
|
||||||
Token::String { value } => &**value,
|
Token::String { value } => &**value,
|
||||||
|
|
Loading…
Reference in New Issue