Refactor mutability
This commit is contained in:
parent
9d074ddd19
commit
4fcad8c6a4
|
@ -15,7 +15,7 @@ pub enum Token {
|
|||
#[token("else")] Else,
|
||||
#[token("in")] In,
|
||||
#[token("let")] Let,
|
||||
#[token("var")] Var,
|
||||
#[token("mut")] Mut,
|
||||
#[token("interface")] Interface,
|
||||
#[token("impl")] Impl,
|
||||
|
||||
|
|
|
@ -30,7 +30,7 @@ impl ColorTheme {
|
|||
pub fn token_style(&self, token: &Token) -> &Style {
|
||||
use Token::*;
|
||||
match token {
|
||||
Struct | Function | For | If | Else | In | Let | Var => &self.keyword,
|
||||
Struct | Function | For | If | Else | In | Let | Mut => &self.keyword,
|
||||
BinaryInteger | OctalInteger | DecimalInteger => &self.literal,
|
||||
SingleLineComment => &self.comment,
|
||||
Error => &self.error,
|
||||
|
|
60
src/parse.rs
60
src/parse.rs
|
@ -13,12 +13,20 @@ impl<'a> ParseTree<'a> {
|
|||
let mut declarations = Vec::new();
|
||||
let mut associated_struct = None;
|
||||
while let Some(tok) = lexer.next() {
|
||||
if let Some(_) = associated_struct {
|
||||
if tok != Token::Function {
|
||||
lexer.panic_message("Expected fn");
|
||||
if let Some(struct_name) = associated_struct {
|
||||
let mut mutable = false;
|
||||
if tok == Token::Mut {
|
||||
mutable = true;
|
||||
lexer.eat_expect(Token::Function);
|
||||
} else if tok != Token::Function {
|
||||
lexer.panic_message("Expected fn or mut");
|
||||
}
|
||||
|
||||
declarations.push(Definition::build_function(associated_struct, lexer));
|
||||
declarations.push(Definition::build_function(
|
||||
Some((struct_name, mutable)),
|
||||
lexer,
|
||||
));
|
||||
|
||||
associated_struct = None;
|
||||
} else {
|
||||
match tok {
|
||||
|
@ -26,7 +34,7 @@ impl<'a> ParseTree<'a> {
|
|||
Token::Function => declarations.push(Definition::build_function(None, lexer)),
|
||||
Token::Interface => declarations.push(Definition::build_interface(lexer)),
|
||||
Token::Identifier => associated_struct = Some(lexer.slice()),
|
||||
_ => lexer.panic_message("Expected associated struct identifier, fn or struct"),
|
||||
_ => lexer.panic_message("Expected function, struct, or interface"),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -42,7 +50,7 @@ pub enum Definition<'a> {
|
|||
members: Vec<StructMember<'a>>,
|
||||
},
|
||||
Function {
|
||||
associated_struct: Option<&'a str>,
|
||||
associated_struct: Option<(&'a str, bool)>,
|
||||
name: &'a str,
|
||||
signature: FnSig<'a>,
|
||||
body: FnBody<'a>,
|
||||
|
@ -78,7 +86,10 @@ impl<'a> Definition<'a> {
|
|||
Self::Struct { name, members }
|
||||
}
|
||||
|
||||
pub fn build_function(associated_struct: Option<&'a str>, lexer: &mut Lexer<'a>) -> Self {
|
||||
pub fn build_function(
|
||||
associated_struct: Option<(&'a str, bool)>,
|
||||
lexer: &mut Lexer<'a>,
|
||||
) -> Self {
|
||||
let name = lexer.eat_expect_id();
|
||||
let (signature, tok) = FnSig::build(lexer);
|
||||
|
||||
|
@ -204,15 +215,6 @@ impl<'a> FnBody<'a> {
|
|||
_ => lexer.panic_message("Unexpected token"),
|
||||
}
|
||||
}
|
||||
Token::Var => {
|
||||
let (statement, next) = Statement::build_var(lexer);
|
||||
statements.push(statement);
|
||||
match next {
|
||||
Token::Semicolon => {}
|
||||
Token::BraceClose => break,
|
||||
_ => lexer.panic_message("Unexpected token"),
|
||||
}
|
||||
}
|
||||
Token::Identifier => match Expr::build_start(tok, lexer) {
|
||||
(None, Token::Semicolon | Token::BraceClose) => {}
|
||||
(Some(expr), Token::Semicolon) => statements.push(Statement::Expr(expr)),
|
||||
|
@ -223,7 +225,7 @@ impl<'a> FnBody<'a> {
|
|||
_ => lexer.panic_message("Unexpected token"),
|
||||
},
|
||||
Token::BraceClose => break,
|
||||
_ => lexer.panic_message("Expected var, let, or assign"),
|
||||
_ => lexer.panic_message("Expected let or expression"),
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -294,6 +296,7 @@ pub enum BinaryOp {
|
|||
Sub,
|
||||
Mul,
|
||||
Div,
|
||||
Assign,
|
||||
Less,
|
||||
LessEq,
|
||||
Greater,
|
||||
|
@ -311,6 +314,7 @@ impl BinaryOp {
|
|||
OpSub => Some(Sub),
|
||||
OpMul => Some(Mul),
|
||||
OpDiv => Some(Div),
|
||||
OpAssign => Some(Assign),
|
||||
OpLess => Some(Less),
|
||||
OpLessEq => Some(LessEq),
|
||||
OpGreater => Some(Greater),
|
||||
|
@ -335,10 +339,7 @@ pub enum Statement<'a> {
|
|||
Expr(Expr<'a>),
|
||||
Let {
|
||||
var: &'a str,
|
||||
expr: Expr<'a>,
|
||||
},
|
||||
Var {
|
||||
var: &'a str,
|
||||
mutable: bool,
|
||||
expr: Expr<'a>,
|
||||
},
|
||||
If {
|
||||
|
@ -356,15 +357,18 @@ impl<'a> Statement<'a> {
|
|||
}
|
||||
|
||||
pub fn build_let(lexer: &mut Lexer<'a>) -> (Self, Token) {
|
||||
let var = lexer.eat_expect_id();
|
||||
let (expr, tail) = Self::eat_assign(lexer);
|
||||
(Self::Let { var, expr }, tail)
|
||||
}
|
||||
let mut mutable = false;
|
||||
let var = match lexer.next().unwrap() {
|
||||
Token::Identifier => lexer.slice(),
|
||||
Token::Mut => {
|
||||
mutable = true;
|
||||
lexer.eat_expect_id()
|
||||
}
|
||||
_ => lexer.panic_message("Unexpected token"),
|
||||
};
|
||||
|
||||
pub fn build_var(lexer: &mut Lexer<'a>) -> (Self, Token) {
|
||||
let var = lexer.eat_expect_id();
|
||||
let (expr, tail) = Self::eat_assign(lexer);
|
||||
(Self::Var { var, expr }, tail)
|
||||
(Self::Let { var, mutable, expr }, tail)
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -37,9 +37,9 @@ fn count_neighbors(BitArray array, i32 i, i32 j) i32 {
|
|||
}
|
||||
|
||||
// associated function for the World struct
|
||||
World fn set_next(i32 i, i32 j) {
|
||||
World mut fn set_next(i32 i, i32 j) {
|
||||
// members on this World struct can be accessed with `.`
|
||||
var numdots = .numdots; // mutable variables are defined with `var`
|
||||
let mut numdots = .numdots; // mutable variables are defined with `let mut`
|
||||
let neighbors = count_neighbors(.current, i, j);
|
||||
|
||||
// `if` statements are expressions
|
||||
|
@ -61,7 +61,6 @@ World fn set_next(i32 i, i32 j) {
|
|||
};
|
||||
|
||||
if next != 0 {
|
||||
// TODO: mutability rules for arguments?
|
||||
if i < .xmin { .xmin = i; }
|
||||
if i > .xmax { .xmax = i; }
|
||||
if j < .ymin { .ymin = j; }
|
||||
|
@ -85,7 +84,6 @@ World fn next_cycle() {
|
|||
// TODO: figure out better range definitions, or ditch them altogether
|
||||
for y in 0..(.ysize) {
|
||||
for x in 0..(.xsize) {
|
||||
// TODO: mutability rules
|
||||
.current.set_bit(x, y, .next.get_bit(x, y));
|
||||
}
|
||||
}
|
||||
|
|
|
@ -3,9 +3,9 @@ fn free_floating(i32 arg1, i32 arg2) ReturnType {
|
|||
}
|
||||
|
||||
// associated function for the World struct
|
||||
World fn set_next(i32 i, i32 j) {
|
||||
World mut fn set_next(i32 i, i32 j) {
|
||||
// members on this World struct can be accessed with `.`
|
||||
var numdots = .numdots; // mutable variables are defined with `var`
|
||||
let mut numdots = .numdots; // mutable variables are defined with `let mut`
|
||||
let neighbors = count_neighbors(.current, i, j);
|
||||
|
||||
// `if` statements are expressions
|
||||
|
@ -27,7 +27,6 @@ World fn set_next(i32 i, i32 j) {
|
|||
};
|
||||
|
||||
if next != 0 {
|
||||
// TODO: mutability rules for arguments?
|
||||
if i < .xmin { .xmin = i; }
|
||||
if i > .xmax { .xmax = i; }
|
||||
if j < .ymin { .ymin = j; }
|
||||
|
|
Loading…
Reference in New Issue