diff options
| author | Edvard Thörnros <edvard.thornros@gmail.com> | 2021-02-18 19:51:59 +0100 |
|---|---|---|
| committer | GitHub <noreply@github.com> | 2021-02-18 19:51:59 +0100 |
| commit | f7bf054ac41f6bc31f1f6c4229357cca36f1d708 (patch) | |
| tree | d6cc2e077c96ce0cfb683c0e3e0c2ab3fe4b997c /src/lib.rs | |
| parent | 6bb72c7bbe2bbb1b627809d4b52f44a77bdb4b33 (diff) | |
| parent | 75b2027c7b545b9827607f17ea7444f67622999d (diff) | |
| download | sylt-f7bf054ac41f6bc31f1f6c4229357cca36f1d708.tar.gz | |
Merge pull request #70 from FredTheDino/fix-constant-bug
Fix constant bug
Diffstat (limited to 'src/lib.rs')
| -rw-r--r-- | src/lib.rs | 50 |
1 files changed, 44 insertions, 6 deletions
@@ -151,7 +151,7 @@ impl From<&Type> for Value { Type::String => Value::String(Rc::new("".to_string())), Type::Function(_, _) => Value::Function( Vec::new(), - Rc::new(RefCell::new(Block::empty_with_type(ty)))), + Rc::new(RefCell::new(Block::stubbed_block(ty)))), } } } @@ -626,35 +626,58 @@ mod op { } #[derive(Debug)] +enum BlockLinkState { + Linked, + Unlinked, + Nothing, +} + +#[derive(Debug)] pub struct Block { pub ty: Type, upvalues: Vec<(usize, bool, Type)>, + linking: BlockLinkState, pub name: String, pub file: PathBuf, ops: Vec<Op>, last_line_offset: usize, line_offsets: HashMap<usize, usize>, - line: usize, } impl Block { - fn new(name: &str, file: &Path, line: usize) -> Self { + fn new(name: &str, file: &Path) -> Self { Self { ty: Type::Void, upvalues: Vec::new(), + linking: BlockLinkState::Nothing, + name: String::from(name), file: file.to_owned(), ops: Vec::new(), last_line_offset: 0, line_offsets: HashMap::new(), - line, } } + fn mark_constant(&mut self) { + if self.upvalues.is_empty() { + return; + } + self.linking = BlockLinkState::Unlinked; + } + + fn link(&mut self) { + self.linking = BlockLinkState::Linked; + } + + fn needs_linking(&self) -> bool { + matches!(self.linking, BlockLinkState::Unlinked) + } + // Used to create empty functions. - fn empty_with_type(ty: &Type) -> Self { - let mut block = Block::new("/empty/", Path::new(""), 0); + fn stubbed_block(ty: &Type) -> Self { + let mut block = Block::new("/empty/", Path::new("")); block.ty = ty.clone(); block } @@ -857,6 +880,21 @@ mod tests { } #[test] + fn call_before_link() { + let prog = " +a := 1 +f() +c := 5 + +f :: fn { + c <=> 5 +} +a + "; + assert_errs!(run_string(prog, true, Vec::new()), [ErrorKind::InvalidProgram, ErrorKind::RuntimeTypeError(_, _)]); + } + + #[test] fn unused_variable() { assert_errs!(run_string("a := 1", true, Vec::new()), [ErrorKind::SyntaxError(1, _)]); } |
