Skip to content

Commit

Permalink
Unify structs and arrays on the parser side. Unify that all Vecs on t…
Browse files Browse the repository at this point in the history
…he parser must return Box<Positioned<Obj>> (Box<Decorated<Positioned<Obj>>> for statements).

New positions are mostly wasted. But they are here in case they're later needed.
  • Loading branch information
Ivorforce committed Apr 25, 2024
1 parent db8ea47 commit bcae7fa
Show file tree
Hide file tree
Showing 15 changed files with 158 additions and 138 deletions.
72 changes: 40 additions & 32 deletions src/monoteny_grammar.lalrpop
Original file line number Diff line number Diff line change
Expand Up @@ -77,8 +77,27 @@ pub Block: Block = {
<statements: Box<Decorated<Positioned<(<Statement> ";")>>>*> => Block { <> }
};

Function: Box<Function> = {
"def" <interface: FunctionInterface> <body: ("::" <FunctionBody>)?> => Box::new(Function { <> }),
Struct: Struct = {
"(" <arguments: OptionalFinalSeparatorList<Box<Positioned<StructArgument>>, ",">> ")" => Struct { <> }
}

StructArgument: StructArgument = {
<key: Identifier> ":" <value: Expression> <type_declaration: ("'" <Expression>)?> => StructArgument { key: ParameterKey::Name(key), value: value, type_declaration },
<value: Expression> <type_declaration: ("'" <Expression>)?> => StructArgument { key: ParameterKey::Positional, value: value, type_declaration },
<start:@L> <key: Identifier> <end:@R> ":" <type_declaration: ("'" <Expression>)?> => StructArgument { key: ParameterKey::Name(key.clone()), value: Expression::from(vec![Box::new(positioned(Term::Identifier(key.clone()), start, end))]), type_declaration: type_declaration },
}

Array: Array = {
"[" <arguments: OptionalFinalSeparatorList<Box<Positioned<ArrayArgument>>, ",">> "]" => Array { <> }
}

ArrayArgument: ArrayArgument = {
<key: Expression> ":" <value: Expression> <type_declaration: ("'" <Expression>)?> => ArrayArgument { key: Some(key), value, type_declaration },
<value: Expression> <type_declaration: ("'" <Expression>)?>=> ArrayArgument { key: None, value, type_declaration },
}

Function: Function = {
"def" <interface: FunctionInterface> <body: ("::" <FunctionBody>)?> => Function { <> },
}

FunctionInterface: FunctionInterface = {
Expand All @@ -91,35 +110,35 @@ FunctionBody: Expression = {

// =============================== Trait =====================================

Trait: Box<TraitDefinition> = {
"trait" <name: Identifier> "{" <statements: (<Box<Positioned<Statement>>> ";")*> "}" => Box::new(TraitDefinition { <> }),
Trait: TraitDefinition = {
"trait" <name: Identifier> "{" <block: Box<Block>> "}" => TraitDefinition { <> },
}

Conformance: Box<TraitConformanceDeclaration> = {
"declare" <declared_for: Expression> "is" <declared: Identifier> "{" <statements: (<Box<Positioned<Statement>>> ";")*> "}" => Box::new(TraitConformanceDeclaration { <> }),
Conformance: TraitConformanceDeclaration = {
"declare" <declared_for: Expression> "is" <declared: Identifier> "{" <block: Box<Block>> "}" => TraitConformanceDeclaration { <> },
}

// =============================== Statement =====================================


Statement: Statement = {
<mutability: VariableDeclarationMutability> <identifier: Identifier> <type_declaration: ("'" <Expression>)?> <assignment: ("=" <Expression>)?> => Statement::VariableDeclaration { mutability, identifier, type_declaration, assignment },
"upd" <target: Expression> "=" <new_value: Expression> => Statement::VariableUpdate { <> },
"return" <Expression?> => Statement::Return(<>),
IfThenElse => Statement::IfThenElse(<>),
Expression => Statement::Expression(<>),
Function => Statement::FunctionDeclaration(<>),
Trait => Statement::Trait(<>),
Conformance => Statement::Conformance(<>),
<mutability: VariableDeclarationMutability> <identifier: Identifier> <type_declaration: ("'" <Box<Expression>>)?> <assignment: ("=" <Box<Expression>>)?> => Statement::VariableDeclaration { mutability, identifier, type_declaration, assignment },
"upd" <target: Box<Expression>> "=" <new_value: Box<Expression>> => Statement::VariableUpdate { <> },
"return" <Box<Expression>?> => Statement::Return(<>),
Box<IfThenElse> => Statement::IfThenElse(<>),
Box<Expression> => Statement::Expression(<>),
Box<Function> => Statement::FunctionDeclaration(<>),
Box<Trait> => Statement::Trait(<>),
Box<Conformance> => Statement::Conformance(<>),
}

VariableDeclarationMutability: Mutability = {
"let" => Mutability::Immutable,
"var" => Mutability::Mutable,
}

IfThenElse: Box<IfThenElse> = {
"if" <condition: Expression> "::" <consequent: Expression> <alternative: ("else" "::" <Expression>)?> => Box::new(IfThenElse { <> }),
IfThenElse: IfThenElse = {
"if" <condition: Expression> "::" <consequent: Expression> <alternative: ("else" "::" <Expression>)?> => IfThenElse { <> },
}

// =============================== Expression =====================================
Expand All @@ -134,27 +153,16 @@ Term: Term = {
IntLiteral => Term::IntLiteral(<>),
RealLiteral => Term::RealLiteral(<>),
"." => Term::Dot,
"[" <OptionalFinalSeparatorList<ArrayArgument, ",">> "]" => Term::Array(<>),
"(" <OptionalFinalSeparatorList<StructArgument, ",">> ")" => Term::Struct(<>),
Box<Array> => Term::Array(<>),
Box<Struct> => Term::Struct(<>),
"\"" <Box<Positioned<StringPart>>*> "\"" => Term::StringLiteral(<>),
"{" <Block> "}" => Term::Block(<>),
"{" <Box<Block>> "}" => Term::Block(<>),
<start:@L> <e: !> <end:@R> => { errors.push(e.clone()); Term::Error(derive_error(&e, start, end)) },
}

StructArgument: StructArgument = {
<key: Identifier> ":" <value: Expression> <type_declaration: ("'" <Expression>)?> => StructArgument { key: ParameterKey::Name(key), value: value, type_declaration },
<value: Expression> <type_declaration: ("'" <Expression>)?> => StructArgument { key: ParameterKey::Positional, value: value, type_declaration },
<start:@L> <key: Identifier> <end:@R> ":" <type_declaration: ("'" <Expression>)?> => StructArgument { key: ParameterKey::Name(key.clone()), value: Expression::from(vec![Box::new(positioned(Term::Identifier(key.clone()), start, end))]), type_declaration: type_declaration },
}

ArrayArgument: ArrayArgument = {
<key: Expression> ":" <value: Expression> <type_declaration: ("'" <Expression>)?> => ArrayArgument { key: Some(key), value, type_declaration },
<value: Expression> <type_declaration: ("'" <Expression>)?>=> ArrayArgument { key: None, value, type_declaration },
}

StringPart: StringPart = {
StringLiteral => StringPart::Literal(<>.to_string()),
"(" <OptionalFinalSeparatorList<StructArgument, ",">> ")" => StringPart::Object(<>),
Box<Struct> => StringPart::Object(<>),
}

// =============================== Util =====================================
Expand All @@ -168,7 +176,7 @@ Positioned<Element>: Positioned<Element> = {
}

Decorated<Element>: Decorated<Element> = {
<decorations: ("!" "[" <OptionalFinalSeparatorList<ArrayArgument, ",">> "]")?> <value: Element> => Decorated { decorations: decorations.unwrap_or(vec![]), value },
<decorations: ("!" <Array>)?> <value: Element> => Decorated { decorations: decorations.unwrap_or(Array { arguments: vec![] }), value },
}

OptionalFinalSeparatorList<Element, Separator>: Vec<Element> = {
Expand Down
89 changes: 52 additions & 37 deletions src/parser/ast.rs
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ use itertools::Itertools;
use crate::error::{RResult, RuntimeError};
use crate::program::allocation::Mutability;
use crate::program::functions::ParameterKey;
use crate::util::fmt::{write_comma_separated_list, write_space_separated_list};
use crate::util::fmt::write_separated_display;
use crate::util::position::Positioned;

// =============================== Global =====================================
Expand Down Expand Up @@ -38,14 +38,14 @@ pub struct KeyedParameter {
#[derive(Eq, PartialEq, Clone)]
pub struct TraitDefinition {
pub name: String,
pub statements: Vec<Box<Positioned<Statement>>>,
pub block: Box<Block>,
}

#[derive(Eq, PartialEq, Clone)]
pub struct TraitConformanceDeclaration {
pub declared_for: Expression,
pub declared: String,
pub statements: Vec<Box<Positioned<Statement>>>,
pub block: Box<Block>,
}

#[derive(Eq, PartialEq, Clone)]
Expand All @@ -63,12 +63,12 @@ pub enum Statement {
VariableDeclaration {
mutability: Mutability,
identifier: String,
type_declaration: Option<Expression>,
assignment: Option<Expression>
type_declaration: Option<Box<Expression>>,
assignment: Option<Box<Expression>>
},
VariableUpdate { target: Expression, new_value: Expression },
Expression(Expression),
Return(Option<Expression>),
VariableUpdate { target: Box<Expression>, new_value: Box<Expression> },
Expression(Box<Expression>),
Return(Option<Box<Expression>>),
FunctionDeclaration(Box<Function>),
Trait(Box<TraitDefinition>),
Conformance(Box<TraitConformanceDeclaration>),
Expand Down Expand Up @@ -124,12 +124,18 @@ pub enum Term {
Dot,
IntLiteral(String),
RealLiteral(String),
Struct(Vec<StructArgument>),
Array(Vec<ArrayArgument>),
Struct(Box<Struct>),
Array(Box<Array>),
StringLiteral(Vec<Box<Positioned<StringPart>>>),
Block(Block),
Block(Box<Block>),
}

#[derive(Eq, PartialEq, Clone)]
pub struct Struct { pub arguments: Vec<Box<Positioned<StructArgument>>> }

#[derive(Eq, PartialEq, Clone)]
pub struct Array { pub arguments: Vec<Box<Positioned<ArrayArgument>>> }

#[derive(Eq, PartialEq, Clone)]
pub struct StructArgument {
pub key: ParameterKey,
Expand All @@ -153,12 +159,12 @@ pub enum FunctionCallType {
#[derive(PartialEq, Eq, Clone)]
pub enum StringPart {
Literal(String),
Object(Vec<StructArgument>),
Object(Box<Struct>),
}

#[derive(PartialEq, Eq, Clone)]
pub struct Decorated<T> {
pub decorations: Vec<ArrayArgument>,
pub decorations: Array,
pub value: T,
}

Expand All @@ -173,6 +179,22 @@ impl Mutability {
}
}

impl Display for Struct {
fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
write!(f, "(")?;
write_separated_display(f, ", ", self.arguments.iter().map(|f| &f.value))?;
write!(f, ")")
}
}

impl Display for Array {
fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
write!(f, "[")?;
write_separated_display(f, ", ", self.arguments.iter().map(|f| &f.value))?;
write!(f, "]")
}
}

impl Display for Block {
fn fmt(&self, fmt: &mut Formatter) -> Result<(), Error> {
for item in self.statements.iter() {
Expand Down Expand Up @@ -257,7 +279,7 @@ impl Display for Statement {

impl Display for Expression {
fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
write_space_separated_list(f, &self.iter().map(|b| &b.value).collect_vec())
write_separated_display(f, " ", self.0.iter().map(|b| &b.value))
}
}

Expand All @@ -276,16 +298,12 @@ impl Display for Term {
}
write!(fmt, "\"")
},
Term::Struct(arguments) => {
write!(fmt, "(")?;
write_comma_separated_list(fmt, arguments)?;
write!(fmt, ")")
},
Term::Array(arguments) => {
write!(fmt, "[")?;
write_comma_separated_list(fmt, arguments)?;
write!(fmt, "]")
},
Term::Struct(struct_) => {
write!(fmt, "{}", struct_)
}
Term::Array(array) => {
write!(fmt, "{}", array)
}
Term::Block(block) => {
write!(fmt, "{{\n{}}}", block)
}
Expand Down Expand Up @@ -328,39 +346,36 @@ impl Display for StringPart {
fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
match self {
StringPart::Literal(s) => write!(f, "{}", s),
StringPart::Object(arguments) => {
write!(f, "(")?;
write_comma_separated_list(f, arguments)?;
write!(f, ")")
},
StringPart::Object(struct_) => write!(f, "{}", struct_),
}
}
}

impl<V: Display> Display for Decorated<V> {
fn fmt(&self, fmt: &mut Formatter<'_>) -> std::fmt::Result {
write!(fmt, "![")?;
write_comma_separated_list(fmt, &self.decorations)?;
write!(fmt, "]\n{}", self.value)
if self.decorations.arguments.is_empty() {
return write!(fmt, "{}", self.value)
}
write!(fmt, "!{}\n{}", self.decorations, self.value)
}
}

impl<V> Decorated<V> {
pub fn decorations_as_vec(&self) -> RResult<Vec<&Expression>> {
return self.decorations.iter().map(|d| {
if d.key.is_some() {
return self.decorations.arguments.iter().map(|d| {
if d.value.key.is_some() {
return Err(RuntimeError::new("Decorations cannot have keys.".to_string()))
}
if d.type_declaration.is_some() {
if d.value.type_declaration.is_some() {
return Err(RuntimeError::new("Decorations cannot have type declarations.".to_string()))
}

Ok(&d.value)
Ok(&d.value.value)
}).try_collect()
}

pub fn no_decorations(&self) -> RResult<()> {
if !self.decorations.is_empty() {
if !self.decorations.arguments.is_empty() {
return Err(RuntimeError::new("Decorations are not supported in this context.".to_string()))
}

Expand Down
4 changes: 2 additions & 2 deletions src/parser/tests.rs
Original file line number Diff line number Diff line change
Expand Up @@ -44,11 +44,11 @@ mod tests {
match floor_div.interface.expression.iter().map(|t| &t.value).collect_vec()[..] {
[Term::Identifier(i), Term::Struct(s)] => {
assert_eq!(i, "_add");
assert_eq!(s.len(), 2);
assert_eq!(s.arguments.len(), 2);
}
_ => panic!()
}
assert_eq!(parsed.statements[1].decorations.len(), 1);
assert_eq!(parsed.statements[1].decorations.arguments.len(), 1);

Ok(())
}
Expand Down
5 changes: 2 additions & 3 deletions src/program/functions.rs
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ use uuid::Uuid;
use crate::program::function_object::{FunctionCallExplicity, FunctionRepresentation, FunctionTargetType};
use crate::program::traits::{Trait, TraitBinding};
use crate::program::types::TypeProto;
use crate::util::fmt::write_separated_debug;

#[derive(Clone, PartialEq, Eq, Hash)]
pub enum ParameterKey {
Expand Down Expand Up @@ -239,9 +240,7 @@ impl DebugWithOptions<FunctionRepresentation> for FunctionInterface {

if representation.call_explicity == FunctionCallExplicity::Explicit {
write!(fmt, "(")?;
for parameter in self.parameters.iter().skip(head).enumerate() {
write!(fmt, "{:?}, ", &parameter)?;
}
write_separated_debug(fmt, ", ", self.parameters.iter().skip(head))?;
write!(fmt, ")")?;
}

Expand Down
4 changes: 2 additions & 2 deletions src/program/traits.rs
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ use crate::program::function_object::FunctionRepresentation;
use crate::program::functions::{FunctionHead, FunctionInterface, FunctionType};
use crate::program::generics::{GenericAlias, TypeForest};
use crate::program::types::{TypeProto, TypeUnit};
use crate::util::fmt::{write_comma_separated_list, write_keyval};
use crate::util::fmt::{write_separated_display, write_keyval};
use crate::util::hash;

/// The definition of some trait.
Expand Down Expand Up @@ -503,7 +503,7 @@ impl Debug for Trait {
write!(fmt, "{}<{}>", self.name, self.id)?;
if !self.generics.is_empty() {
write!(fmt, "<")?;
write_comma_separated_list(fmt, &self.generics.keys().collect_vec())?;
write_separated_display(fmt, ", ", self.generics.keys())?;
write!(fmt, ">")?;
}
Ok(())
Expand Down
4 changes: 2 additions & 2 deletions src/program/types.rs
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ use uuid::Uuid;

use crate::program::generics::GenericAlias;
use crate::program::traits::Trait;
use crate::util::fmt::write_comma_separated_list_debug;
use crate::util::fmt::write_separated_debug;

#[derive(Clone, PartialEq, Eq, Hash)]
pub struct TypeProto {
Expand Down Expand Up @@ -41,7 +41,7 @@ impl Debug for TypeProto {
write!(fmt, "{:?}", self.unit)?;
if !self.arguments.is_empty() {
write!(fmt, "<")?;
write_comma_separated_list_debug(fmt, &self.arguments)?;
write_separated_debug(fmt, ", ", self.arguments.iter())?;
write!(fmt, ">")?;
}
Ok(())
Expand Down
Loading

0 comments on commit bcae7fa

Please sign in to comment.