Structs implemented
albeit very inefficiently
This commit is contained in:
parent
f0de3c3d12
commit
5d15d60ab6
@ -16,6 +16,7 @@ type Reduction<T> = (T, Option<SideEffect>);
|
||||
enum ReducedValue {
|
||||
StringLiteral(Rc<String>),
|
||||
ListLiteral(VecDeque<Expression>),
|
||||
StructLiteral(VecDeque<(Rc<String>, Expression)>),
|
||||
Number(f64),
|
||||
Lambda(Function),
|
||||
}
|
||||
@ -27,6 +28,7 @@ impl From<ReducedValue> for Expression {
|
||||
ReducedValue::StringLiteral(n) => Expression::StringLiteral(n),
|
||||
ReducedValue::Lambda(f) => Expression::Lambda(f),
|
||||
ReducedValue::ListLiteral(items) => Expression::ListLiteral(items),
|
||||
ReducedValue::StructLiteral(items) => Expression::StructLiteral(items),
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -38,6 +40,7 @@ impl From<Expression> for ReducedValue {
|
||||
Expression::StringLiteral(n) => ReducedValue::StringLiteral(n),
|
||||
Expression::Lambda(f) => ReducedValue::Lambda(f),
|
||||
Expression::ListLiteral(items) => ReducedValue::ListLiteral(items),
|
||||
Expression::StructLiteral(items) => ReducedValue::StructLiteral(items),
|
||||
_ => panic!("trying to store a non-fully-reduced variable"),
|
||||
}
|
||||
}
|
||||
@ -120,6 +123,9 @@ impl Evaluable for Expression {
|
||||
ListLiteral(ref items) => {
|
||||
items.iter().any(|x| x.is_reducible())
|
||||
}
|
||||
StructLiteral(ref items) => {
|
||||
items.iter().any(|pair| pair.1.is_reducible())
|
||||
}
|
||||
_ => true,
|
||||
}
|
||||
}
|
||||
@ -214,6 +220,7 @@ impl<'a> Evaluator<'a> {
|
||||
}
|
||||
}
|
||||
|
||||
//TODO I probably want another Expression variant that holds a ReducedValue
|
||||
fn reduce_expr(&mut self, expression: Expression) -> Reduction<Expression> {
|
||||
match expression {
|
||||
Null => (Null, None),
|
||||
@ -348,6 +355,14 @@ impl<'a> Evaluator<'a> {
|
||||
(Null, None)
|
||||
}
|
||||
}
|
||||
(StructLiteral(items), StringLiteral(s)) => {
|
||||
for item in items {
|
||||
if s == item.0 {
|
||||
return (item.1.clone(), None); //TODO this is hella inefficient
|
||||
}
|
||||
}
|
||||
(Null, None)
|
||||
},
|
||||
_ => (Null, None)
|
||||
}
|
||||
}
|
||||
@ -365,6 +380,23 @@ impl<'a> Evaluator<'a> {
|
||||
}
|
||||
(ListLiteral(exprs), side_effect)
|
||||
},
|
||||
|
||||
StructLiteral(mut items) => {
|
||||
let mut side_effect = None;
|
||||
for pair in items.iter_mut() {
|
||||
if pair.1.is_reducible() {
|
||||
take_mut::take(pair, |pair| {
|
||||
let (name, expr) = pair;
|
||||
let (a, b) = self.reduce_expr(expr);
|
||||
side_effect = b;
|
||||
(name, a)
|
||||
});
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
(StructLiteral(items), side_effect)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -12,15 +12,17 @@ use std::convert::From;
|
||||
// statement := declaration | expression
|
||||
// declaration := FN prototype LCurlyBrace (statement)* RCurlyBrace
|
||||
// prototype := identifier LParen identlist RParen
|
||||
// identlist := Ident (Comma Ident)* | e
|
||||
// exprlist := Expression (Comma Expression)* | e
|
||||
// identlist := Ident (Comma Ident)* | ε
|
||||
// exprlist := Expression (Comma Expression)* | ε
|
||||
// itemlist := Ident COLON Expression (Comma Ident COLON Expression)* | ε
|
||||
//
|
||||
// expression := postop_expression (op postop_expression)*
|
||||
// postop_expression := primary_expression postop
|
||||
// primary_expression := number_expr | String | identifier_expr | paren_expr | conditional_expr | while_expr | lambda_expr | list_expr
|
||||
// primary_expression := number_expr | String | identifier_expr | paren_expr | conditional_expr | while_expr | lambda_expr | list_expr | struct_expr
|
||||
// number_expr := (PLUS | MINUS ) number_expr | Number
|
||||
// identifier_expr := call_expression | Variable
|
||||
// list_expr := LSquareBracket exprlist RSquareBracket
|
||||
// struct_expr := LCurlyBrace itemlist RCurlyBrace
|
||||
// call_expression := Identifier LParen exprlist RParen
|
||||
// while_expr := WHILE primary_expression LCurlyBrace (expression delimiter)* RCurlyBrace
|
||||
// paren_expr := LParen expression RParen
|
||||
@ -75,6 +77,7 @@ pub enum Expression {
|
||||
While(Box<Expression>, Vec<Expression>),
|
||||
Index(Box<Expression>, Box<Expression>),
|
||||
ListLiteral(VecDeque<Expression>),
|
||||
StructLiteral(VecDeque<(Rc<String>, Expression)>),
|
||||
}
|
||||
|
||||
#[derive(Clone, Debug)]
|
||||
@ -83,6 +86,7 @@ pub enum Callable {
|
||||
Lambda(Function),
|
||||
}
|
||||
|
||||
//TODO this ought to be ReducedExpression
|
||||
impl fmt::Display for Expression {
|
||||
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
||||
use self::Expression::*;
|
||||
@ -104,6 +108,17 @@ impl fmt::Display for Expression {
|
||||
}
|
||||
write!(f, " ]")
|
||||
}
|
||||
StructLiteral(ref items) => {
|
||||
write!(f, "{} ", "{")?;
|
||||
let mut iter = items.iter().peekable();
|
||||
while let Some(pair) = iter.next() {
|
||||
write!(f, "{}: {}", pair.0, pair.1)?;
|
||||
if let Some(_) = iter.peek() {
|
||||
write!(f, ", ")?;
|
||||
}
|
||||
}
|
||||
write!(f, "{} ", "}")
|
||||
}
|
||||
_ => write!(f, "UNIMPLEMENTED"),
|
||||
}
|
||||
}
|
||||
@ -361,6 +376,24 @@ impl Parser {
|
||||
Ok(exprs)
|
||||
}
|
||||
|
||||
fn itemlist(&mut self) -> ParseResult<VecDeque<(Rc<String>, Expression)>> {
|
||||
let mut items = VecDeque::new();
|
||||
loop {
|
||||
if let Some(RCurlyBrace) = self.peek() {
|
||||
break;
|
||||
}
|
||||
let name = expect_identifier!(self);
|
||||
expect!(self, Colon);
|
||||
let expr = self.expression()?;
|
||||
items.push_back((name, expr));
|
||||
match self.peek() {
|
||||
Some(Comma) => {self.next();},
|
||||
_ => break,
|
||||
};
|
||||
}
|
||||
Ok(items)
|
||||
}
|
||||
|
||||
fn body(&mut self) -> ParseResult<Vec<Statement>> {
|
||||
let statements = delimiter_block!(
|
||||
self,
|
||||
@ -446,6 +479,7 @@ impl Parser {
|
||||
Some(Token::LParen) => self.paren_expr()?,
|
||||
Some(Keyword(Kw::Fn)) => self.lambda_expr()?,
|
||||
Some(Token::LSquareBracket) => self.list_expr()?,
|
||||
Some(Token::LCurlyBrace) => self.struct_expr()?,
|
||||
Some(e) => {
|
||||
return ParseError::result_from_str(&format!("Expected primary expression, got \
|
||||
{:?}",
|
||||
@ -463,6 +497,13 @@ impl Parser {
|
||||
Ok(Expression::ListLiteral(VecDeque::from(exprlist)))
|
||||
}
|
||||
|
||||
fn struct_expr(&mut self) -> ParseResult<Expression> {
|
||||
expect!(self, LCurlyBrace);
|
||||
let struct_items = self.itemlist()?;
|
||||
expect!(self, RCurlyBrace);
|
||||
Ok(Expression::StructLiteral(struct_items))
|
||||
}
|
||||
|
||||
fn number_expression(&mut self) -> ParseResult<Expression> {
|
||||
let mut multiplier = 1;
|
||||
loop {
|
||||
|
Loading…
Reference in New Issue
Block a user