Skip to content

Commit fa5edf5

Browse files
committed
fixed infinite loop bug with error sync on panic_mode and made methods partially functional
1 parent 5b9f067 commit fa5edf5

File tree

3 files changed

+98
-64
lines changed

3 files changed

+98
-64
lines changed

examples/struct/methods.syn

Lines changed: 10 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -22,15 +22,17 @@ impl Player {
2222
};
2323
}
2424

25-
// func move(self: Self) {
26-
// self.position.x = self.position.x + speed;
27-
// self.position.y = self.position.y + speed;
28-
// }
25+
func move(self: Self) {
26+
self.position.x = self.position.x + speed;
27+
self.position.y = self.position.y + speed;
28+
}
2929
}
3030

3131
func main() {
32-
let player = Player::new();
33-
// println("player position before: {}", player.position);
34-
// player.move();
35-
// println("player position after: {}", player.position);
32+
let speed = 1.0;
33+
let player = Player::new(speed);
34+
35+
println("player position before: {}", player.position);
36+
player.move();
37+
println("player position after: {}", player.position);
3638
}

src/compiler.rs

Lines changed: 54 additions & 48 deletions
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,7 @@ pub struct Compiler {
2828
loop_state: LoopState,
2929

3030
had_error: bool,
31+
had_sync_err: bool,
3132
panic_mode: bool,
3233
declarative_mode: bool, // used to prevent non-declarative top level code -- for structure
3334
}
@@ -104,12 +105,16 @@ impl Compiler {
104105
had_error: false,
105106
panic_mode: false,
106107
declarative_mode: false,
108+
had_sync_err: false,
107109
}
108110
}
109111

110112
pub fn compile(mut self) -> Result<Program, Vec<CompilerError>> {
111113
let mut errs = Vec::new();
112114
loop {
115+
if self.had_sync_err {
116+
break;
117+
}
113118
match self.declaration() {
114119
Ok(_) => (),
115120
Err(err) => {
@@ -138,31 +143,36 @@ impl Compiler {
138143
}
139144
}
140145

141-
fn synchronize(&mut self) -> bool {
146+
// synchronize until:
147+
// end of file
148+
// the start of a new statement (func, impl, struct, while, if, ...)
149+
// end of a statement (;)
150+
fn synchronize(&mut self) {
142151
self.panic_mode = false;
143-
let mut prev;
144152
loop {
145153
if self.curr.tokn == Token::EOF {
146-
return true;
154+
return;
147155
}
148-
prev = match self.peek() {
156+
let next = match self.peek() {
149157
Ok(t) => t.tokn,
150-
Err(_) => return false,
158+
Err(_) => return { self.had_sync_err = true; },
151159
};
152-
match prev {
153-
Token::Func
154-
| Token::Let
155-
| Token::If
156-
| Token::While
157-
| Token::Print
158-
| Token::Return => return true,
160+
match next {
161+
Token::Impl |
162+
Token::Struct |
163+
Token::Func |
164+
Token::Let |
165+
Token::If |
166+
Token::While |
167+
Token::Print |
168+
Token::Return => return,
159169
_ => (),
160170
};
161171
if self.next().is_err() {
162-
return false;
172+
return { self.had_sync_err = true; };
163173
};
164-
if prev == Token::SemiColon {
165-
return true;
174+
if next == Token::SemiColon {
175+
return;
166176
}
167177
}
168178
}
@@ -171,6 +181,9 @@ impl Compiler {
171181
// grammar agnostic methods
172182
impl Compiler {
173183
fn declaration(&mut self) -> Result<(), CompilerError> {
184+
if self.panic_mode {
185+
self.synchronize();
186+
}
174187
match self.peek()?.tokn {
175188
Token::Let => {
176189
self.declarative_mode = true;
@@ -194,7 +207,6 @@ impl Compiler {
194207
self.declarative_mode = true;
195208
self.next()?;
196209
self.expect(Token::Identifer, "expected struct name")?;
197-
198210
let base_ptr = match self.resolve_global(&self.curr.lexm) {
199211
Some(base_ptr) => base_ptr,
200212
None => return Err(self.error("undefined struct"))
@@ -211,16 +223,12 @@ impl Compiler {
211223
self.expect(Token::RightBrace, "expected '}'")?;
212224
self.push_bytecode(ByteCode::GGet(base_ptr))?;
213225
self.push_bytecode(ByteCode::StructImpl(methods_count))?;
214-
215226
self.declarative_mode = false;
216227
}
217228
_ => {
218229
return self.statement();
219230
}
220231
};
221-
if self.panic_mode {
222-
self.synchronize();
223-
}
224232
Ok(())
225233
}
226234

@@ -272,9 +280,9 @@ impl Compiler {
272280

273281
fn parse_precedence(&mut self, precedence: Precedence) -> Result<(), CompilerError> {
274282
self.next()?;
283+
let can_assign = precedence <= Precedence::Assignment;
275284
match self.get_rule(self.curr.tokn).prefix {
276285
Some(prefix) => {
277-
let can_assign = precedence <= Precedence::Assignment;
278286
prefix(self, can_assign)?;
279287
loop {
280288
let infix_tok = self.peek()?;
@@ -420,15 +428,10 @@ impl Compiler {
420428
Ok(())
421429
}
422430

423-
fn compile_method(&mut self) -> Result<(), CompilerError> {
431+
fn compile_method(&mut self) -> Result<ObjPointer, CompilerError> {
424432
self.expect(Token::Identifer, "expected the method's name")?;
425-
let token = self.curr.clone();
426-
let func = self.compile_func_body(token.lexm.clone())?;
427-
match self.prog.chunk_load_obj(0, Object::Function(func), token) {
428-
Ok(idx) => idx,
429-
Err(err) => return Err(self.error(err)),
430-
};
431-
Ok(())
433+
let func = self.compile_func_body(self.curr.lexm.clone())?;
434+
self.load_obj(Object::Function(func))
432435
}
433436

434437
fn compile_func(&mut self) -> Result<(), CompilerError> {
@@ -471,7 +474,8 @@ impl Compiler {
471474
self.load_obj(Object::Nil)?;
472475
self.push_bytecode(ByteCode::Ret)?;
473476
self.end_scope()?;
474-
Ok(Func { name, arity, retype, chunk: self.chunk.take().unwrap() })
477+
let chunk = self.chunk.take().unwrap();
478+
Ok(Func { name, arity, retype, chunk })
475479
}
476480

477481
fn compile_params(&mut self) -> Result<usize, CompilerError> {
@@ -497,23 +501,24 @@ impl Compiler {
497501

498502
fn compile_struct(&mut self) -> Result<(), CompilerError> {
499503
self.expect(Token::Identifer, "expected struct name")?;
500-
let tok = self.curr.clone();
501-
self.expect(Token::LeftBrace, "expected '{'")?;
502-
let mut fields = std::collections::HashMap::new();
503-
while !self.check_with_eof(Token::RightBrace)? {
504-
self.expect(Token::Identifer, "expected struct member name")?;
505-
let field_name = self.curr.lexm.clone();
506-
self.expect(Token::Colon, "expected ':' as a type seperator")?;
507-
fields.insert(field_name, StructMember::Field{typ: self.compile_type()?});
508-
self.check(Token::Comma)?;
509-
}
510-
if self.curr.tokn != Token::RightBrace {
511-
return Err(self.error("expected '}'"));
504+
let mut le_struct = Struct::new(self.curr.lexm.clone());
505+
let rollback = self.curr.clone();
506+
{
507+
self.expect(Token::LeftBrace, "expected '{'")?;
508+
while !self.check_with_eof(Token::RightBrace)? {
509+
self.expect(Token::Identifer, "expected struct member name")?;
510+
let field_name = self.curr.lexm.clone();
511+
self.expect(Token::Colon, "expected ':' as a type seperator")?;
512+
le_struct.add_member(field_name, StructMember::Field{typ: self.compile_type()?});
513+
self.check(Token::Comma)?;
514+
}
515+
if self.curr.tokn != Token::RightBrace {
516+
return Err(self.error("expected '}'"));
517+
}
512518
}
513519
let temp = self.curr.clone();
520+
self.curr = rollback;
514521
{
515-
let le_struct = Struct{ name: tok.lexm.clone(), fields };
516-
self.curr = tok;
517522
let byte = if self.scope_depth > 0 {
518523
self.push_local(Some(TypeInfo::Struct(le_struct.clone())))?;
519524
ByteCode::LDef
@@ -723,6 +728,7 @@ impl Compiler {
723728
Ok(())
724729
}
725730

731+
// does a lookup for the current identifer from the ineer most scope to the global scope
726732
fn identifer(&mut self, can_assign: bool) -> Result<(), CompilerError> {
727733
let name = self.curr.lexm.clone();
728734
match self.resolve_local(name.as_str()) {
@@ -736,9 +742,9 @@ impl Compiler {
736742
None => return Err(self.error("expected struct declaration"))
737743
};
738744
let mut set = HashSet::new();
739-
for _ in 0..base.fields.len() {
745+
for _ in 0..base.members.len() {
740746
self.expect(Token::Identifer, "expected member name")?;
741-
if base.fields.get(&self.curr.lexm).is_none() {
747+
if base.members.get(&self.curr.lexm).is_none() {
742748
return Err(self.error("undefined member in struct"));
743749
}
744750
if set.contains(&self.curr.lexm) {
@@ -768,10 +774,10 @@ impl Compiler {
768774
None => return Err(self.error("expected struct declaration"))
769775
};
770776
let mut set = HashSet::new();
771-
for _ in 0..base.fields.len() {
777+
for _ in 0..base.members.len() {
772778
self.expect(Token::Identifer, "expected member name")?;
773779
let name = self.curr.lexm.clone();
774-
if base.fields.get(&name).is_none() {
780+
if base.members.get(&name).is_none() {
775781
return Err(self.error("undefined member in struct"));
776782
}
777783
if set.contains(&name) {

src/vm.rs

Lines changed: 34 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -266,7 +266,33 @@ impl Object {
266266
#[derive(Clone, PartialEq, Debug)]
267267
pub struct Struct {
268268
pub name: String,
269-
pub fields: HashMap<String, StructMember>,
269+
pub members: HashMap<String, StructMember>,
270+
fields_count: usize,
271+
methods_count: usize,
272+
}
273+
274+
impl Struct {
275+
pub fn new(name: String) -> Self {
276+
Self {
277+
name,
278+
fields_count: 0,
279+
methods_count: 0,
280+
members: HashMap::new(),
281+
}
282+
}
283+
284+
pub fn add_member(&mut self, name: String, member: StructMember) {
285+
match member {
286+
StructMember::Field { .. } => {
287+
self.fields_count += 1;
288+
self.members.insert(name, member)
289+
},
290+
StructMember::Method { .. } => {
291+
self.methods_count += 1;
292+
self.members.insert(name, member)
293+
}
294+
};
295+
}
270296
}
271297

272298
#[derive(Clone, PartialEq, Debug)]
@@ -430,7 +456,7 @@ impl VM {
430456

431457
pub fn exec(mut self) -> Result<(), VMError> {
432458
while self.frame.ip < self.prog.chunks[self.frame.func.chunk as usize].count() {
433-
self.prog.chunk_disassemble_one(self.frame.func.chunk, self.frame.ip);
459+
// self.prog.chunk_disassemble_one(self.frame.func.chunk, self.frame.ip);
434460
let byte = self.prog.chunks[self.frame.func.chunk as usize].code[self.frame.ip];
435461
match byte {
436462
ByteCode::Push(i) => {
@@ -689,8 +715,8 @@ impl VM {
689715
Object::Struct(ref base) => base,
690716
_ => unreachable!(),
691717
};
692-
if let Some(StructMember::Method { ptr }) = base.fields.get(&method_name) {
693-
println!("{:?} -> {:?}", ptr, self.get_obj(*ptr));
718+
if let Some(StructMember::Method { ptr }) = base.members.get(&method_name) {
719+
// println!("{:?} -> {:?}", ptr, self.get_obj(*ptr));
694720
self.push(ptr.clone());
695721
} else {
696722
return Err(self.error(
@@ -735,16 +761,16 @@ impl VM {
735761
self.push(val);
736762
}
737763
ByteCode::StructImpl(methods_count) => {
738-
let base = self.pop();
764+
let base_ptr = self.pop();
739765
for _ in 0..methods_count {
740766
let method_ptr = self.pop();
741767
let method_name = match self.get_obj(method_ptr) {
742768
Object::Function(le_method) => le_method.name.clone(),
743769
_ => unreachable!()
744770
};
745771
// TODO: this is awful
746-
if let Object::Struct(base) = self.get_obj_mut(base)? {
747-
base.fields.insert(method_name, StructMember::Method { ptr: method_ptr });
772+
if let Object::Struct(base) = self.get_obj_mut(base_ptr)? {
773+
base.add_member(method_name, StructMember::Method { ptr: method_ptr });
748774
} else {
749775
unreachable!();
750776
}
@@ -763,7 +789,7 @@ impl VM {
763789
_ => unreachable!()
764790
};
765791
let mut data = HashMap::new();
766-
for _ in 0..base.fields.len() {
792+
for _ in 0..base.fields_count {
767793
if let Object::String(k) = self.pop_obj() {
768794
let v = self.pop();
769795
data.insert(k, v);

0 commit comments

Comments
 (0)