Run rustfmt on ast module
This commit is contained in:
parent
765a0bec58
commit
5d04a020dc
@ -1,18 +1,22 @@
|
|||||||
#![allow(clippy::upper_case_acronyms)]
|
#![allow(clippy::upper_case_acronyms)]
|
||||||
#![allow(clippy::enum_variant_names)]
|
#![allow(clippy::enum_variant_names)]
|
||||||
|
|
||||||
use std::rc::Rc;
|
use std::{
|
||||||
use std::convert::{AsRef, From};
|
convert::{AsRef, From},
|
||||||
|
rc::Rc,
|
||||||
|
};
|
||||||
|
|
||||||
mod visitor;
|
|
||||||
mod operators;
|
mod operators;
|
||||||
|
mod visitor;
|
||||||
|
|
||||||
pub use operators::{PrefixOp, BinOp};
|
pub use operators::{BinOp, PrefixOp};
|
||||||
pub use visitor::*;
|
pub use visitor::*;
|
||||||
|
|
||||||
use crate::derivative::Derivative;
|
use crate::{
|
||||||
use crate::tokenizing::Location;
|
derivative::Derivative,
|
||||||
use crate::identifier::{Id, define_id_kind};
|
identifier::{define_id_kind, Id},
|
||||||
|
tokenizing::Location,
|
||||||
|
};
|
||||||
|
|
||||||
define_id_kind!(ASTItem);
|
define_id_kind!(ASTItem);
|
||||||
|
|
||||||
@ -29,32 +33,32 @@ pub type ItemId = Id<ASTItem>;
|
|||||||
#[derive(Derivative, Debug)]
|
#[derive(Derivative, Debug)]
|
||||||
#[derivative(PartialEq)]
|
#[derivative(PartialEq)]
|
||||||
pub struct AST {
|
pub struct AST {
|
||||||
#[derivative(PartialEq="ignore")]
|
#[derivative(PartialEq = "ignore")]
|
||||||
pub id: ItemId,
|
pub id: ItemId,
|
||||||
pub statements: Block,
|
pub statements: Block,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Derivative, Debug, Clone)]
|
#[derive(Derivative, Debug, Clone)]
|
||||||
#[derivative(PartialEq)]
|
#[derivative(PartialEq)]
|
||||||
pub struct Statement {
|
pub struct Statement {
|
||||||
#[derivative(PartialEq="ignore")]
|
#[derivative(PartialEq = "ignore")]
|
||||||
pub id: ItemId,
|
pub id: ItemId,
|
||||||
#[derivative(PartialEq="ignore")]
|
#[derivative(PartialEq = "ignore")]
|
||||||
pub location: Location,
|
pub location: Location,
|
||||||
pub kind: StatementKind,
|
pub kind: StatementKind,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Debug, PartialEq, Clone)]
|
#[derive(Debug, PartialEq, Clone)]
|
||||||
pub enum StatementKind {
|
pub enum StatementKind {
|
||||||
Expression(Expression),
|
Expression(Expression),
|
||||||
Declaration(Declaration),
|
Declaration(Declaration),
|
||||||
Import(ImportSpecifier),
|
Import(ImportSpecifier),
|
||||||
Module(ModuleSpecifier),
|
Module(ModuleSpecifier),
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Debug, Clone, PartialEq, Default)]
|
#[derive(Debug, Clone, PartialEq, Default)]
|
||||||
pub struct Block {
|
pub struct Block {
|
||||||
pub statements: Vec<Statement>
|
pub statements: Vec<Statement>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl From<Vec<Statement>> for Block {
|
impl From<Vec<Statement>> for Block {
|
||||||
@ -80,59 +84,37 @@ pub type ParamName = Rc<String>;
|
|||||||
#[derive(Debug, Derivative, Clone)]
|
#[derive(Debug, Derivative, Clone)]
|
||||||
#[derivative(PartialEq)]
|
#[derivative(PartialEq)]
|
||||||
pub struct QualifiedName {
|
pub struct QualifiedName {
|
||||||
#[derivative(PartialEq="ignore")]
|
#[derivative(PartialEq = "ignore")]
|
||||||
pub id: ItemId,
|
pub id: ItemId,
|
||||||
pub components: Vec<Rc<String>>,
|
pub components: Vec<Rc<String>>,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Debug, PartialEq, Clone)]
|
#[derive(Debug, PartialEq, Clone)]
|
||||||
pub struct FormalParam {
|
pub struct FormalParam {
|
||||||
pub name: ParamName,
|
pub name: ParamName,
|
||||||
pub default: Option<Expression>,
|
pub default: Option<Expression>,
|
||||||
pub anno: Option<TypeIdentifier>
|
pub anno: Option<TypeIdentifier>,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Debug, PartialEq, Clone)]
|
#[derive(Debug, PartialEq, Clone)]
|
||||||
pub enum Declaration {
|
pub enum Declaration {
|
||||||
FuncSig(Signature),
|
FuncSig(Signature),
|
||||||
FuncDecl(Signature, Block),
|
FuncDecl(Signature, Block),
|
||||||
TypeDecl {
|
TypeDecl { name: TypeSingletonName, body: TypeBody, mutable: bool },
|
||||||
name: TypeSingletonName,
|
//TODO this needs to be more sophisticated
|
||||||
body: TypeBody,
|
TypeAlias { alias: Rc<String>, original: Rc<String> },
|
||||||
mutable: bool
|
Binding { name: Rc<String>, constant: bool, type_anno: Option<TypeIdentifier>, expr: Expression },
|
||||||
},
|
Impl { type_name: TypeIdentifier, interface_name: Option<TypeSingletonName>, block: Vec<Declaration> },
|
||||||
//TODO this needs to be more sophisticated
|
Interface { name: Rc<String>, signatures: Vec<Signature> },
|
||||||
TypeAlias {
|
Annotation { name: Rc<String>, arguments: Vec<Expression> },
|
||||||
alias: Rc<String>,
|
|
||||||
original: Rc<String>,
|
|
||||||
},
|
|
||||||
Binding {
|
|
||||||
name: Rc<String>,
|
|
||||||
constant: bool,
|
|
||||||
type_anno: Option<TypeIdentifier>,
|
|
||||||
expr: Expression,
|
|
||||||
},
|
|
||||||
Impl {
|
|
||||||
type_name: TypeIdentifier,
|
|
||||||
interface_name: Option<TypeSingletonName>,
|
|
||||||
block: Vec<Declaration>,
|
|
||||||
},
|
|
||||||
Interface {
|
|
||||||
name: Rc<String>,
|
|
||||||
signatures: Vec<Signature>
|
|
||||||
},
|
|
||||||
Annotation {
|
|
||||||
name: Rc<String>,
|
|
||||||
arguments: Vec<Expression>
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Debug, PartialEq, Clone)]
|
#[derive(Debug, PartialEq, Clone)]
|
||||||
pub struct Signature {
|
pub struct Signature {
|
||||||
pub name: Rc<String>,
|
pub name: Rc<String>,
|
||||||
pub operator: bool,
|
pub operator: bool,
|
||||||
pub params: Vec<FormalParam>,
|
pub params: Vec<FormalParam>,
|
||||||
pub type_anno: Option<TypeIdentifier>,
|
pub type_anno: Option<TypeIdentifier>,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Debug, PartialEq, Clone)]
|
#[derive(Debug, PartialEq, Clone)]
|
||||||
@ -141,184 +123,147 @@ pub struct TypeBody(pub Vec<Variant>);
|
|||||||
#[derive(Debug, Derivative, Clone)]
|
#[derive(Debug, Derivative, Clone)]
|
||||||
#[derivative(PartialEq)]
|
#[derivative(PartialEq)]
|
||||||
pub struct Variant {
|
pub struct Variant {
|
||||||
#[derivative(PartialEq="ignore")]
|
#[derivative(PartialEq = "ignore")]
|
||||||
pub id: ItemId,
|
pub id: ItemId,
|
||||||
pub name: Rc<String>,
|
pub name: Rc<String>,
|
||||||
pub kind: VariantKind,
|
pub kind: VariantKind,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Debug, PartialEq, Clone)]
|
#[derive(Debug, PartialEq, Clone)]
|
||||||
pub enum VariantKind {
|
pub enum VariantKind {
|
||||||
UnitStruct,
|
UnitStruct,
|
||||||
TupleStruct(Vec<TypeIdentifier>),
|
TupleStruct(Vec<TypeIdentifier>),
|
||||||
Record(Vec<(Rc<String>, TypeIdentifier)>),
|
Record(Vec<(Rc<String>, TypeIdentifier)>),
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Debug, Derivative, Clone)]
|
#[derive(Debug, Derivative, Clone)]
|
||||||
#[derivative(PartialEq)]
|
#[derivative(PartialEq)]
|
||||||
pub struct Expression {
|
pub struct Expression {
|
||||||
#[derivative(PartialEq="ignore")]
|
#[derivative(PartialEq = "ignore")]
|
||||||
pub id: ItemId,
|
pub id: ItemId,
|
||||||
pub kind: ExpressionKind,
|
pub kind: ExpressionKind,
|
||||||
pub type_anno: Option<TypeIdentifier>
|
pub type_anno: Option<TypeIdentifier>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Expression {
|
impl Expression {
|
||||||
pub fn new(id: ItemId, kind: ExpressionKind) -> Expression {
|
pub fn new(id: ItemId, kind: ExpressionKind) -> Expression {
|
||||||
Expression { id, kind, type_anno: None }
|
Expression { id, kind, type_anno: None }
|
||||||
}
|
}
|
||||||
|
|
||||||
#[cfg(test)]
|
#[cfg(test)]
|
||||||
pub fn with_anno(id: ItemId, kind: ExpressionKind, type_anno: TypeIdentifier) -> Expression {
|
pub fn with_anno(id: ItemId, kind: ExpressionKind, type_anno: TypeIdentifier) -> Expression {
|
||||||
Expression { id, kind, type_anno: Some(type_anno) }
|
Expression { id, kind, type_anno: Some(type_anno) }
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Debug, PartialEq, Clone)]
|
#[derive(Debug, PartialEq, Clone)]
|
||||||
pub enum TypeIdentifier {
|
pub enum TypeIdentifier {
|
||||||
Tuple(Vec<TypeIdentifier>),
|
Tuple(Vec<TypeIdentifier>),
|
||||||
Singleton(TypeSingletonName)
|
Singleton(TypeSingletonName),
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Debug, PartialEq, Clone)]
|
#[derive(Debug, PartialEq, Clone)]
|
||||||
pub struct TypeSingletonName {
|
pub struct TypeSingletonName {
|
||||||
pub name: Rc<String>,
|
pub name: Rc<String>,
|
||||||
pub params: Vec<TypeIdentifier>,
|
pub params: Vec<TypeIdentifier>,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Debug, PartialEq, Clone)]
|
#[derive(Debug, PartialEq, Clone)]
|
||||||
pub enum ExpressionKind {
|
pub enum ExpressionKind {
|
||||||
NatLiteral(u64),
|
NatLiteral(u64),
|
||||||
FloatLiteral(f64),
|
FloatLiteral(f64),
|
||||||
StringLiteral(Rc<String>),
|
StringLiteral(Rc<String>),
|
||||||
BoolLiteral(bool),
|
BoolLiteral(bool),
|
||||||
BinExp(BinOp, Box<Expression>, Box<Expression>),
|
BinExp(BinOp, Box<Expression>, Box<Expression>),
|
||||||
PrefixExp(PrefixOp, Box<Expression>),
|
PrefixExp(PrefixOp, Box<Expression>),
|
||||||
TupleLiteral(Vec<Expression>),
|
TupleLiteral(Vec<Expression>),
|
||||||
Value(QualifiedName),
|
Value(QualifiedName),
|
||||||
NamedStruct {
|
NamedStruct { name: QualifiedName, fields: Vec<(Rc<String>, Expression)> },
|
||||||
name: QualifiedName,
|
Call { f: Box<Expression>, arguments: Vec<InvocationArgument> },
|
||||||
fields: Vec<(Rc<String>, Expression)>,
|
Index { indexee: Box<Expression>, indexers: Vec<Expression> },
|
||||||
},
|
IfExpression { discriminator: Option<Box<Expression>>, body: Box<IfExpressionBody> },
|
||||||
Call {
|
WhileExpression { condition: Option<Box<Expression>>, body: Block },
|
||||||
f: Box<Expression>,
|
ForExpression { enumerators: Vec<Enumerator>, body: Box<ForBody> },
|
||||||
arguments: Vec<InvocationArgument>,
|
Lambda { params: Vec<FormalParam>, type_anno: Option<TypeIdentifier>, body: Block },
|
||||||
},
|
ListLiteral(Vec<Expression>),
|
||||||
Index {
|
|
||||||
indexee: Box<Expression>,
|
|
||||||
indexers: Vec<Expression>,
|
|
||||||
},
|
|
||||||
IfExpression {
|
|
||||||
discriminator: Option<Box<Expression>>,
|
|
||||||
body: Box<IfExpressionBody>,
|
|
||||||
},
|
|
||||||
WhileExpression {
|
|
||||||
condition: Option<Box<Expression>>,
|
|
||||||
body: Block,
|
|
||||||
},
|
|
||||||
ForExpression {
|
|
||||||
enumerators: Vec<Enumerator>,
|
|
||||||
body: Box<ForBody>,
|
|
||||||
},
|
|
||||||
Lambda {
|
|
||||||
params: Vec<FormalParam>,
|
|
||||||
type_anno: Option<TypeIdentifier>,
|
|
||||||
body: Block,
|
|
||||||
},
|
|
||||||
ListLiteral(Vec<Expression>),
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Debug, PartialEq, Clone)]
|
#[derive(Debug, PartialEq, Clone)]
|
||||||
pub enum InvocationArgument {
|
pub enum InvocationArgument {
|
||||||
Positional(Expression),
|
Positional(Expression),
|
||||||
Keyword {
|
Keyword { name: Rc<String>, expr: Expression },
|
||||||
name: Rc<String>,
|
Ignored,
|
||||||
expr: Expression,
|
|
||||||
},
|
|
||||||
Ignored
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Debug, PartialEq, Clone)]
|
#[derive(Debug, PartialEq, Clone)]
|
||||||
pub enum IfExpressionBody {
|
pub enum IfExpressionBody {
|
||||||
SimpleConditional {
|
SimpleConditional { then_case: Block, else_case: Option<Block> },
|
||||||
then_case: Block,
|
SimplePatternMatch { pattern: Pattern, then_case: Block, else_case: Option<Block> },
|
||||||
else_case: Option<Block>
|
CondList(Vec<ConditionArm>),
|
||||||
},
|
|
||||||
SimplePatternMatch {
|
|
||||||
pattern: Pattern,
|
|
||||||
then_case: Block,
|
|
||||||
else_case: Option<Block>
|
|
||||||
},
|
|
||||||
CondList(Vec<ConditionArm>)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Debug, PartialEq, Clone)]
|
#[derive(Debug, PartialEq, Clone)]
|
||||||
pub struct ConditionArm {
|
pub struct ConditionArm {
|
||||||
pub condition: Condition,
|
pub condition: Condition,
|
||||||
pub guard: Option<Expression>,
|
pub guard: Option<Expression>,
|
||||||
pub body: Block,
|
pub body: Block,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Debug, PartialEq, Clone)]
|
#[derive(Debug, PartialEq, Clone)]
|
||||||
pub enum Condition {
|
pub enum Condition {
|
||||||
Pattern(Pattern),
|
Pattern(Pattern),
|
||||||
TruncatedOp(BinOp, Expression),
|
TruncatedOp(BinOp, Expression),
|
||||||
Expression(Expression),
|
Expression(Expression),
|
||||||
Else,
|
Else,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Debug, PartialEq, Clone)]
|
#[derive(Debug, PartialEq, Clone)]
|
||||||
pub enum Pattern {
|
pub enum Pattern {
|
||||||
Ignored,
|
Ignored,
|
||||||
TuplePattern(Vec<Pattern>),
|
TuplePattern(Vec<Pattern>),
|
||||||
Literal(PatternLiteral),
|
Literal(PatternLiteral),
|
||||||
TupleStruct(QualifiedName, Vec<Pattern>),
|
TupleStruct(QualifiedName, Vec<Pattern>),
|
||||||
Record(QualifiedName, Vec<(Rc<String>, Pattern)>),
|
Record(QualifiedName, Vec<(Rc<String>, Pattern)>),
|
||||||
VarOrName(QualifiedName),
|
VarOrName(QualifiedName),
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Debug, PartialEq, Clone)]
|
#[derive(Debug, PartialEq, Clone)]
|
||||||
pub enum PatternLiteral {
|
pub enum PatternLiteral {
|
||||||
NumPattern {
|
NumPattern { neg: bool, num: ExpressionKind },
|
||||||
neg: bool,
|
StringPattern(Rc<String>),
|
||||||
num: ExpressionKind,
|
BoolPattern(bool),
|
||||||
},
|
|
||||||
StringPattern(Rc<String>),
|
|
||||||
BoolPattern(bool),
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Debug, PartialEq, Clone)]
|
#[derive(Debug, PartialEq, Clone)]
|
||||||
pub struct Enumerator {
|
pub struct Enumerator {
|
||||||
pub id: Rc<String>,
|
pub id: Rc<String>,
|
||||||
pub generator: Expression,
|
pub generator: Expression,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Debug, PartialEq, Clone)]
|
#[derive(Debug, PartialEq, Clone)]
|
||||||
pub enum ForBody {
|
pub enum ForBody {
|
||||||
MonadicReturn(Expression),
|
MonadicReturn(Expression),
|
||||||
StatementBlock(Block),
|
StatementBlock(Block),
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Debug, Derivative, Clone)]
|
#[derive(Debug, Derivative, Clone)]
|
||||||
#[derivative(PartialEq)]
|
#[derivative(PartialEq)]
|
||||||
pub struct ImportSpecifier {
|
pub struct ImportSpecifier {
|
||||||
#[derivative(PartialEq="ignore")]
|
#[derivative(PartialEq = "ignore")]
|
||||||
pub id: ItemId,
|
pub id: ItemId,
|
||||||
pub path_components: Vec<Rc<String>>,
|
pub path_components: Vec<Rc<String>>,
|
||||||
pub imported_names: ImportedNames
|
pub imported_names: ImportedNames,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Debug, PartialEq, Clone)]
|
#[derive(Debug, PartialEq, Clone)]
|
||||||
pub enum ImportedNames {
|
pub enum ImportedNames {
|
||||||
All,
|
All,
|
||||||
LastOfPath,
|
LastOfPath,
|
||||||
List(Vec<Rc<String>>)
|
List(Vec<Rc<String>>),
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
#[derive(Debug, PartialEq, Clone)]
|
#[derive(Debug, PartialEq, Clone)]
|
||||||
pub struct ModuleSpecifier {
|
pub struct ModuleSpecifier {
|
||||||
pub name: Rc<String>,
|
pub name: Rc<String>,
|
||||||
pub contents: Block,
|
pub contents: Block,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -4,84 +4,84 @@ use crate::tokenizing::TokenKind;
|
|||||||
|
|
||||||
#[derive(Debug, PartialEq, Clone)]
|
#[derive(Debug, PartialEq, Clone)]
|
||||||
pub struct PrefixOp {
|
pub struct PrefixOp {
|
||||||
sigil: Rc<String>,
|
sigil: Rc<String>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl PrefixOp {
|
impl PrefixOp {
|
||||||
pub fn from_sigil(sigil: &str) -> PrefixOp {
|
pub fn from_sigil(sigil: &str) -> PrefixOp {
|
||||||
PrefixOp { sigil: Rc::new(sigil.to_string()) }
|
PrefixOp { sigil: Rc::new(sigil.to_string()) }
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn sigil(&self) -> &str {
|
pub fn sigil(&self) -> &str {
|
||||||
&self.sigil
|
&self.sigil
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn is_prefix(op: &str) -> bool {
|
pub fn is_prefix(op: &str) -> bool {
|
||||||
matches!(op, "+" | "-" | "!")
|
matches!(op, "+" | "-" | "!")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Debug, PartialEq, Clone)]
|
#[derive(Debug, PartialEq, Clone)]
|
||||||
pub struct BinOp {
|
pub struct BinOp {
|
||||||
sigil: Rc<String>,
|
sigil: Rc<String>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl BinOp {
|
impl BinOp {
|
||||||
pub fn from_sigil(sigil: &str) -> BinOp {
|
pub fn from_sigil(sigil: &str) -> BinOp {
|
||||||
BinOp { sigil: Rc::new(sigil.to_string()) }
|
BinOp { sigil: Rc::new(sigil.to_string()) }
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn sigil(&self) -> &str {
|
pub fn sigil(&self) -> &str {
|
||||||
&self.sigil
|
&self.sigil
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn from_sigil_token(tok: &TokenKind) -> Option<BinOp> {
|
pub fn from_sigil_token(tok: &TokenKind) -> Option<BinOp> {
|
||||||
let s = token_kind_to_sigil(tok)?;
|
let s = token_kind_to_sigil(tok)?;
|
||||||
Some(BinOp::from_sigil(s))
|
Some(BinOp::from_sigil(s))
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn min_precedence() -> i32 {
|
pub fn min_precedence() -> i32 {
|
||||||
i32::min_value()
|
i32::min_value()
|
||||||
}
|
}
|
||||||
pub fn get_precedence_from_token(op_tok: &TokenKind) -> Option<i32> {
|
pub fn get_precedence_from_token(op_tok: &TokenKind) -> Option<i32> {
|
||||||
let s = token_kind_to_sigil(op_tok)?;
|
let s = token_kind_to_sigil(op_tok)?;
|
||||||
Some(binop_precedences(s))
|
Some(binop_precedences(s))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn token_kind_to_sigil(tok: & TokenKind) -> Option<&str> {
|
fn token_kind_to_sigil(tok: &TokenKind) -> Option<&str> {
|
||||||
use self::TokenKind::*;
|
use self::TokenKind::*;
|
||||||
Some(match tok {
|
Some(match tok {
|
||||||
Operator(op) => op.as_str(),
|
Operator(op) => op.as_str(),
|
||||||
Period => ".",
|
Period => ".",
|
||||||
Pipe => "|",
|
Pipe => "|",
|
||||||
Slash => "/",
|
Slash => "/",
|
||||||
LAngleBracket => "<",
|
LAngleBracket => "<",
|
||||||
RAngleBracket => ">",
|
RAngleBracket => ">",
|
||||||
Equals => "=",
|
Equals => "=",
|
||||||
_ => return None
|
_ => return None,
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
fn binop_precedences(s: &str) -> i32 {
|
fn binop_precedences(s: &str) -> i32 {
|
||||||
let default = 10_000_000;
|
let default = 10_000_000;
|
||||||
match s {
|
match s {
|
||||||
"+" => 10,
|
"+" => 10,
|
||||||
"-" => 10,
|
"-" => 10,
|
||||||
"*" => 20,
|
"*" => 20,
|
||||||
"/" => 20,
|
"/" => 20,
|
||||||
"%" => 20,
|
"%" => 20,
|
||||||
"++" => 30,
|
"++" => 30,
|
||||||
"^" => 30,
|
"^" => 30,
|
||||||
"&" => 20,
|
"&" => 20,
|
||||||
"|" => 20,
|
"|" => 20,
|
||||||
">" => 20,
|
">" => 20,
|
||||||
">=" => 20,
|
">=" => 20,
|
||||||
"<" => 20,
|
"<" => 20,
|
||||||
"<=" => 20,
|
"<=" => 20,
|
||||||
"==" => 40,
|
"==" => 40,
|
||||||
"<=>" => 30,
|
"<=>" => 30,
|
||||||
"=" => 5, // Assignment shoudl have highest precedence
|
"=" => 5, // Assignment shoudl have highest precedence
|
||||||
_ => default,
|
_ => default,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -3,17 +3,27 @@ use crate::ast::*;
|
|||||||
#[derive(Debug)]
|
#[derive(Debug)]
|
||||||
pub enum Recursion {
|
pub enum Recursion {
|
||||||
Continue,
|
Continue,
|
||||||
Stop
|
Stop,
|
||||||
}
|
}
|
||||||
|
|
||||||
pub trait ASTVisitor: Sized {
|
pub trait ASTVisitor: Sized {
|
||||||
fn expression(&mut self, _expression: &Expression) -> Recursion { Recursion::Continue }
|
fn expression(&mut self, _expression: &Expression) -> Recursion {
|
||||||
fn declaration(&mut self, _declaration: &Declaration, _id: &ItemId) -> Recursion { Recursion::Continue }
|
Recursion::Continue
|
||||||
|
}
|
||||||
|
fn declaration(&mut self, _declaration: &Declaration, _id: &ItemId) -> Recursion {
|
||||||
|
Recursion::Continue
|
||||||
|
}
|
||||||
|
|
||||||
fn import(&mut self, _import: &ImportSpecifier) -> Recursion { Recursion::Continue }
|
fn import(&mut self, _import: &ImportSpecifier) -> Recursion {
|
||||||
fn module(&mut self, _module: &ModuleSpecifier) -> Recursion { Recursion::Continue }
|
Recursion::Continue
|
||||||
|
}
|
||||||
|
fn module(&mut self, _module: &ModuleSpecifier) -> Recursion {
|
||||||
|
Recursion::Continue
|
||||||
|
}
|
||||||
|
|
||||||
fn pattern(&mut self, _pat: &Pattern) -> Recursion { Recursion::Continue }
|
fn pattern(&mut self, _pat: &Pattern) -> Recursion {
|
||||||
|
Recursion::Continue
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn walk_ast<V: ASTVisitor>(v: &mut V, ast: &AST) {
|
pub fn walk_ast<V: ASTVisitor>(v: &mut V, ast: &AST) {
|
||||||
@ -32,12 +42,11 @@ pub fn walk_block<V: ASTVisitor>(v: &mut V, block: &Block) {
|
|||||||
}
|
}
|
||||||
Import(ref import_spec) => {
|
Import(ref import_spec) => {
|
||||||
v.import(import_spec);
|
v.import(import_spec);
|
||||||
},
|
}
|
||||||
Module(ref module_spec) => {
|
Module(ref module_spec) =>
|
||||||
if let Recursion::Continue = v.module(module_spec) {
|
if let Recursion::Continue = v.module(module_spec) {
|
||||||
walk_block(v, &module_spec.contents);
|
walk_block(v, &module_spec.contents);
|
||||||
}
|
},
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -50,12 +59,7 @@ pub fn walk_declaration<V: ASTVisitor>(v: &mut V, decl: &Declaration, id: &ItemI
|
|||||||
FuncDecl(_sig, block) => {
|
FuncDecl(_sig, block) => {
|
||||||
walk_block(v, block);
|
walk_block(v, block);
|
||||||
}
|
}
|
||||||
Binding {
|
Binding { name: _, constant: _, type_anno: _, expr } => {
|
||||||
name: _,
|
|
||||||
constant: _,
|
|
||||||
type_anno: _,
|
|
||||||
expr,
|
|
||||||
} => {
|
|
||||||
walk_expression(v, expr);
|
walk_expression(v, expr);
|
||||||
}
|
}
|
||||||
_ => (),
|
_ => (),
|
||||||
@ -76,16 +80,14 @@ pub fn walk_expression<V: ASTVisitor>(v: &mut V, expr: &Expression) {
|
|||||||
PrefixExp(_, arg) => {
|
PrefixExp(_, arg) => {
|
||||||
walk_expression(v, arg);
|
walk_expression(v, arg);
|
||||||
}
|
}
|
||||||
TupleLiteral(exprs) => {
|
TupleLiteral(exprs) =>
|
||||||
for expr in exprs {
|
for expr in exprs {
|
||||||
walk_expression(v, expr);
|
walk_expression(v, expr);
|
||||||
}
|
},
|
||||||
}
|
NamedStruct { name: _, fields } =>
|
||||||
NamedStruct { name: _, fields } => {
|
|
||||||
for (_, expr) in fields.iter() {
|
for (_, expr) in fields.iter() {
|
||||||
walk_expression(v, expr);
|
walk_expression(v, expr);
|
||||||
}
|
},
|
||||||
}
|
|
||||||
Call { f, arguments } => {
|
Call { f, arguments } => {
|
||||||
walk_expression(v, f);
|
walk_expression(v, f);
|
||||||
for arg in arguments.iter() {
|
for arg in arguments.iter() {
|
||||||
@ -102,10 +104,7 @@ pub fn walk_expression<V: ASTVisitor>(v: &mut V, expr: &Expression) {
|
|||||||
walk_expression(v, indexer);
|
walk_expression(v, indexer);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
IfExpression {
|
IfExpression { discriminator, body } => {
|
||||||
discriminator,
|
|
||||||
body,
|
|
||||||
} => {
|
|
||||||
if let Some(d) = discriminator.as_ref() {
|
if let Some(d) = discriminator.as_ref() {
|
||||||
walk_expression(v, d);
|
walk_expression(v, d);
|
||||||
}
|
}
|
||||||
@ -126,18 +125,13 @@ pub fn walk_expression<V: ASTVisitor>(v: &mut V, expr: &Expression) {
|
|||||||
ForBody::StatementBlock(block) => walk_block(v, block),
|
ForBody::StatementBlock(block) => walk_block(v, block),
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
Lambda {
|
Lambda { params: _, type_anno: _, body } => {
|
||||||
params: _,
|
|
||||||
type_anno: _,
|
|
||||||
body,
|
|
||||||
} => {
|
|
||||||
walk_block(v, body);
|
walk_block(v, body);
|
||||||
}
|
}
|
||||||
ListLiteral(exprs) => {
|
ListLiteral(exprs) =>
|
||||||
for expr in exprs {
|
for expr in exprs {
|
||||||
walk_expression(v, expr);
|
walk_expression(v, expr);
|
||||||
}
|
},
|
||||||
}
|
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -146,27 +140,20 @@ pub fn walk_if_expr_body<V: ASTVisitor>(v: &mut V, body: &IfExpressionBody) {
|
|||||||
use IfExpressionBody::*;
|
use IfExpressionBody::*;
|
||||||
|
|
||||||
match body {
|
match body {
|
||||||
SimpleConditional {
|
SimpleConditional { then_case, else_case } => {
|
||||||
then_case,
|
|
||||||
else_case,
|
|
||||||
} => {
|
|
||||||
walk_block(v, then_case);
|
walk_block(v, then_case);
|
||||||
if let Some(block) = else_case.as_ref() {
|
if let Some(block) = else_case.as_ref() {
|
||||||
walk_block(v, block)
|
walk_block(v, block)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
SimplePatternMatch {
|
SimplePatternMatch { pattern, then_case, else_case } => {
|
||||||
pattern,
|
|
||||||
then_case,
|
|
||||||
else_case,
|
|
||||||
} => {
|
|
||||||
walk_pattern(v, pattern);
|
walk_pattern(v, pattern);
|
||||||
walk_block(v, then_case);
|
walk_block(v, then_case);
|
||||||
if let Some(block) = else_case.as_ref() {
|
if let Some(block) = else_case.as_ref() {
|
||||||
walk_block(v, block)
|
walk_block(v, block)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
CondList(arms) => {
|
CondList(arms) =>
|
||||||
for arm in arms {
|
for arm in arms {
|
||||||
match arm.condition {
|
match arm.condition {
|
||||||
Condition::Pattern(ref pat) => {
|
Condition::Pattern(ref pat) => {
|
||||||
@ -184,8 +171,7 @@ pub fn walk_if_expr_body<V: ASTVisitor>(v: &mut V, body: &IfExpressionBody) {
|
|||||||
walk_expression(v, guard);
|
walk_expression(v, guard);
|
||||||
}
|
}
|
||||||
walk_block(v, &arm.body);
|
walk_block(v, &arm.body);
|
||||||
}
|
},
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -194,21 +180,18 @@ pub fn walk_pattern<V: ASTVisitor>(v: &mut V, pat: &Pattern) {
|
|||||||
|
|
||||||
if let Recursion::Continue = v.pattern(pat) {
|
if let Recursion::Continue = v.pattern(pat) {
|
||||||
match pat {
|
match pat {
|
||||||
TuplePattern(patterns) => {
|
TuplePattern(patterns) =>
|
||||||
for pat in patterns {
|
for pat in patterns {
|
||||||
walk_pattern(v, pat);
|
walk_pattern(v, pat);
|
||||||
}
|
},
|
||||||
}
|
TupleStruct(_, patterns) =>
|
||||||
TupleStruct(_, patterns) => {
|
|
||||||
for pat in patterns {
|
for pat in patterns {
|
||||||
walk_pattern(v, pat);
|
walk_pattern(v, pat);
|
||||||
}
|
},
|
||||||
}
|
Record(_, name_and_patterns) =>
|
||||||
Record(_, name_and_patterns) => {
|
|
||||||
for (_, pat) in name_and_patterns {
|
for (_, pat) in name_and_patterns {
|
||||||
walk_pattern(v, pat);
|
walk_pattern(v, pat);
|
||||||
}
|
},
|
||||||
}
|
|
||||||
_ => (),
|
_ => (),
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user