Changeset - fbd1526bae2c
examples/make.py
Show inline comments
 
modified file chmod 100644 => 100755
src/protocol/inputsource.rs
Show inline comments
 
@@ -8,7 +8,7 @@ use backtrace::Backtrace;
 
#[derive(Debug, Clone, serde::Serialize, serde::Deserialize)]
 
pub struct InputSource {
 
    filename: String,
 
    input: Vec<u8>,
 
    pub input: Vec<u8>,
 
    line: usize,
 
    column: usize,
 
    offset: usize,
 
@@ -41,13 +41,15 @@ primitive merger(in l, in r, out o) {
 
        if(fires(l))      put(o, get(l));
 
        else if(fires(r)) put(o, get(r));
 
    }
 
}";
 
}
 
";
 

	
 
impl InputSource {
 
    // Constructors
 
    pub fn new<R: io::Read, S: ToString>(filename: S, reader: &mut R) -> io::Result<InputSource> {
 
        let mut vec = STD_LIB_PDL.to_vec();
 
        let mut vec = Vec::new();
 
        reader.read_to_end(&mut vec)?;
 
        vec.extend(STD_LIB_PDL.to_vec());
 
        Ok(InputSource {
 
            filename: filename.to_string(),
 
            input: vec,
src/protocol/mod.rs
Show inline comments
 
@@ -3,7 +3,7 @@ mod ast;
 
mod eval;
 
pub(crate) mod inputsource;
 
mod lexer;
 
// mod library;
 
mod library;
 
mod parser;
 

	
 
lazy_static::lazy_static! {
src/protocol/parser.rs
Show inline comments
 
use crate::protocol::ast::*;
 
use crate::protocol::inputsource::*;
 
use crate::protocol::lexer::*;
 
// use crate::protocol::library;
 
use crate::protocol::library;
 

	
 
// The following indirection is needed due to a bug in the cbindgen tool.
 
type Unit = ();
 
@@ -796,14 +796,14 @@ impl Visitor for BuildSymbolDeclarations {
 
        h[pd].declarations.append(&mut self.declarations);
 
        Ok(())
 
    }
 
    fn visit_import(&mut self, _h: &mut Heap, _import: ImportId) -> VisitorResult {
 
        todo!()
 
        // let vec = library::get_declarations(h, import)?;
 
        // // Destructively iterate over the vector
 
        // for decl in vec {
 
        //     self.checked_add(h, decl)?;
 
        // }
 
        // Ok(())
 
    fn visit_import(&mut self, h: &mut Heap, import: ImportId) -> VisitorResult {
 
        println!("DEBUG: Warning (at {}:{}), import actually not yet implemented", file!(), line!());
 
        let vec = library::get_declarations(h, import)?;
 
        // Destructively iterate over the vector
 
        for decl in vec {
 
            self.checked_add(h, decl)?;
 
        }
 
        Ok(())
 
    }
 
    fn visit_symbol_definition(&mut self, h: &mut Heap, definition: DefinitionId) -> VisitorResult {
 
        let signature = Signature::from_definition(h, definition);
 
@@ -1821,66 +1821,152 @@ impl<'a> Parser<'a> {
 
    }
 
}
 

	
 
// #[cfg(test)]
 
// mod tests {
 
//     extern crate test_generator;
 

	
 
//     use std::fs::File;
 
//     use std::io::Read;
 
//     use std::path::Path;
 

	
 
//     use test_generator::test_resources;
 

	
 
//     use super::*;
 

	
 
//     #[test_resources("testdata/parser/positive/*.pdl")]
 
//     fn batch1(resource: &str) {
 
//         let path = Path::new(resource);
 
//         let mut heap = Heap::new();
 
//         let mut source = InputSource::from_file(&path).unwrap();
 
//         let mut parser = Parser::new(&mut source);
 
//         match parser.parse(&mut heap) {
 
//             Ok(_) => {}
 
//             Err(err) => {
 
//                 println!("{}", err.display(&source));
 
//                 println!("{:?}", err);
 
//                 assert!(false);
 
//             }
 
//         }
 
//     }
 

	
 
//     #[test_resources("testdata/parser/negative/*.pdl")]
 
//     fn batch2(resource: &str) {
 
//         let path = Path::new(resource);
 
//         let expect = path.with_extension("txt");
 
//         let mut heap = Heap::new();
 
//         let mut source = InputSource::from_file(&path).unwrap();
 
//         let mut parser = Parser::new(&mut source);
 
//         match parser.parse(&mut heap) {
 
//             Ok(pd) => {
 
//                 println!("{:?}", heap[pd]);
 
//                 println!("Expected parse error:");
 

	
 
//                 let mut cev: Vec<u8> = Vec::new();
 
//                 let mut f = File::open(expect).unwrap();
 
//                 f.read_to_end(&mut cev).unwrap();
 
//                 println!("{}", String::from_utf8_lossy(&cev));
 
//                 assert!(false);
 
//             }
 
//             Err(err) => {
 
//                 println!("{:?}", err);
 

	
 
//                 let mut vec: Vec<u8> = Vec::new();
 
//                 err.write(&source, &mut vec).unwrap();
 
//                 println!("{}", String::from_utf8_lossy(&vec));
 

	
 
//                 let mut cev: Vec<u8> = Vec::new();
 
//                 let mut f = File::open(expect).unwrap();
 
//                 f.read_to_end(&mut cev).unwrap();
 
//                 println!("{}", String::from_utf8_lossy(&cev));
 

	
 
//                 assert_eq!(vec, cev);
 
//             }
 
//         }
 
//     }
 
// }
 
#[cfg(test)]
 
mod tests {
 
    use std::fs::File;
 
    use std::io::Read;
 
    use std::path::Path;
 

	
 
    use super::*;
 

	
 
    #[test]
 
    fn positive_tests() {
 
        for resource in TestFileIter::new("testdata/parser/positive", "pdl") {
 
            let resource = resource.expect("read testdata filepath");
 
            // println!(" * running: {}", &resource);
 
            let path = Path::new(&resource);
 
            let mut heap = Heap::new();
 
            let mut source = InputSource::from_file(&path).unwrap();
 
            // println!("DEBUG -- input:\n{}", String::from_utf8_lossy(&source.input));
 
            let mut parser = Parser::new(&mut source);
 
            match parser.parse(&mut heap) {
 
                Ok(_) => {}
 
                Err(err) => {
 
                    println!(" > file: {}", &resource);
 
                    println!("{}", err.display(&source));
 
                    println!("{:?}", err);
 
                    assert!(false);
 
                }
 
            }
 
        }
 
    }
 

	
 
    #[test]
 
    fn negative_tests() {
 
        for resource in TestFileIter::new("testdata/parser/negative", "pdl") {
 
            let resource = resource.expect("read testdata filepath");
 
            let path = Path::new(&resource);
 
            let expect = path.with_extension("txt");
 
            let mut heap = Heap::new();
 
            let mut source = InputSource::from_file(&path).unwrap();
 
            let mut parser = Parser::new(&mut source);
 
            match parser.parse(&mut heap) {
 
                Ok(pd) => {
 
                    println!("{:?}", heap[pd]);
 
                    println!("Expected parse error:");
 

	
 
                    let mut cev: Vec<u8> = Vec::new();
 
                    let mut f = File::open(expect).unwrap();
 
                    f.read_to_end(&mut cev).unwrap();
 
                    println!("{}", String::from_utf8_lossy(&cev));
 
                    assert!(false);
 
                }
 
                Err(err) => {
 
                    println!("{:?}", err);
 

	
 
                    let mut vec: Vec<u8> = Vec::new();
 
                    err.write(&source, &mut vec).unwrap();
 
                    println!("{}", String::from_utf8_lossy(&vec));
 

	
 
                    let mut cev: Vec<u8> = Vec::new();
 
                    let mut f = File::open(expect).unwrap();
 
                    f.read_to_end(&mut cev).unwrap();
 
                    println!("{}", String::from_utf8_lossy(&cev));
 

	
 
                    assert_eq!(vec, cev);
 
                }
 
            }
 
        }
 
    }
 

	
 
    #[test]
 
    fn counterexample_tests() {
 
        for resource in TestFileIter::new("testdata/parser/counterexamples", "pdl") {
 
            let resource = resource.expect("read testdata filepath");
 
            let path = Path::new(&resource);
 
            let mut heap = Heap::new();
 
            let mut source = InputSource::from_file(&path).unwrap();
 
            let mut parser = Parser::new(&mut source);
 

	
 
            fn print_header(s: &str) {
 
                println!("{}", "=".repeat(80));
 
                println!(" > File: {}", s);
 
                println!("{}", "=".repeat(80));
 
            }
 

	
 
            match parser.parse(&mut heap) {
 
                Ok(parsed) => {
 
                    print_header(&resource);
 
                    println!("\n  SUCCESS\n\n --- source:\n{}", String::from_utf8_lossy(&source.input));
 
                },
 
                Err(err) => {
 
                    print_header(&resource);
 

	
 
                    let mut err_buf = Vec::new();
 
                    err.write(&source, &mut err_buf);
 
                    println!(
 
                        "\n  FAILURE\n\n --- error:\n{}\n --- source:\n{}",
 
                        String::from_utf8_lossy(&err_buf),
 
                        String::from_utf8_lossy(&source.input)
 
                    )
 
                }
 
            }
 
        }
 
    }
 

	
 
    struct TestFileIter {
 
        iter: std::fs::ReadDir,
 
        root: String,
 
        extension: String
 
    }
 

	
 
    impl TestFileIter {
 
        fn new(root_dir: &str, extension: &str) -> Self {
 
            let path = Path::new(root_dir);
 
            assert!(path.is_dir(), "root '{}' is not a directory", root_dir);
 

	
 
            let iter = std::fs::read_dir(path).expect("list dir contents");
 

	
 
            Self {
 
                iter,
 
                root: root_dir.to_string(),
 
                extension: extension.to_string(),
 
            }
 
        }
 
    }
 

	
 
    impl Iterator for TestFileIter {
 
        type Item = Result<String, String>;
 

	
 
        fn next(&mut self) -> Option<Self::Item> {
 
            while let Some(entry) = self.iter.next() {
 
                if let Err(e) = entry {
 
                    return Some(Err(format!("failed to read dir entry, because: {}", e)));
 
                }
 
                let entry = entry.unwrap();
 

	
 
                let path = entry.path();
 
                if !path.is_file() { continue; }
 

	
 
                let extension = path.extension();
 
                if extension.is_none() { continue; }
 
                let extension = extension.unwrap().to_string_lossy();
 
                if extension != self.extension { continue; }
 

	
 
                return Some(Ok(path.to_string_lossy().to_string()));
 
            }
 

	
 
            None
 
        }
 
    }
 
}
testdata/parser/counterexamples/arity_checking.pdl
Show inline comments
 
new file 100644
 

	
 
int funcy() {
 
    return 5;
 
}
 

	
 
int funcadelic(int a) {
 
    return  a;
 
}
 

	
 
int caller() {
 
    funcy();
 
    funcy(1);
 
    funcy(1, 2, 3);
 
    funcadelic();
 
    funcadelic(5);
 
    return funcadelic(1, 2, 3);
 
}
testdata/parser/counterexamples/declaration_after_function_call.pdl
Show inline comments
 
new file 100644
 
#version 1
 
// My bad: C-ism of declarations on top
 

	
 
int func_b() {
 
    return 5;
 
}
 

	
 
int func_a() {
 
    int a = 2; int b = 3;
 
    int c = 5; func_b(c);
 
    int e = 3;
 

	
 
    return b;
 
}
testdata/parser/counterexamples/definition_order.pdl
Show inline comments
 
new file 100644
 
#version 1
 
// My bad: C-ism of declarations on top
 

	
 
int call_me(int later) {
 
    return later;
 
}
 

	
 
int function() {
 
    int a = 2;
 
    int b = 3;
 

	
 
    int d = call_me(b); // succeeds, because of assignment
 
    call_me(b); // bare function call seems to work, unless we perform assignment afterwards
 

	
 
    int d = 5;
 

	
 
    return 2;
 
}
 
\ No newline at end of file
testdata/parser/counterexamples/empty_file_reporting.pdl
Show inline comments
 
new file 100644
 
// This seems silly, but should be more neatly reported
 
#version 1
 
\ No newline at end of file
testdata/parser/counterexamples/function_type_checks.pdl
Show inline comments
 
new file 100644
 
// Note sure if this is allowed. It seems silly, but could be useful to
 
// select ports to return from. In any case, we are returning an out port from
 
// a function returning an in port
 

	
 
#version 1
 

	
 
in do_something(in a, out b) {
 
    return b;
 
}
 

	
 
float another_something(in a) {
 
    return a;
 
}
 

	
 
whatami yet_another_one(andwhatismypurpose a) {
 
    return a;
 
}
 

	
 
composite main() {}
testdata/parser/counterexamples/import_bad_reporting.pdl
Show inline comments
 
new file 100644
 
// Bad reporting of EOF. Also main parser loop would be fine if pragmas, imports
 
// and declarations are mixed. Maybe force pragmas at top for readability...
 

	
 
#version 1
 

	
 
composite main() {}
 

	
 
#version 2
 

	
 
composite another() {}
 
\ No newline at end of file
testdata/parser/counterexamples/import_stmt.pdl
Show inline comments
 
new file 100644
 
// Import succeeds due to bad parsing (checking for characters, not numbers,
 
// should expect whitespace, then a single number
 

	
 
#version123 456
 

	
 
composite main() {}
testdata/parser/counterexamples/integer_specification.pdl
Show inline comments
 
new file 100644
 
#version 1
 

	
 
int check_integer_specs() {
 
    int a = 0xFF;
 
    // no octal support, but thats fine
 
    int b = 0xxxxFF;
 
    int c = 0x1x2X3x4X5x6X7x8X; // Wut
 
    int d = 1FF;
 
    return a;
 
}
 
\ No newline at end of file
testdata/parser/counterexamples/multiple_versions.pdl
Show inline comments
 
new file 100644
 
#version 1
 
#version 2
 

	
 
composite main() {}
testdata/parser/counterexamples/out_of_order_assignment.pdl
Show inline comments
 
new file 100644
 
// It fails, so that is nice, but it fails due to the wrong reasons
 
// My bad: C-ism of declarations on top
 
bool some_function() {
 
    result_c = false;
 
    bool result_c = true;
 
    return result_c;
 
}
 
\ No newline at end of file
testdata/parser/positive/14.pdl
Show inline comments
 
@@ -32,4 +32,4 @@ primitive binary_replicator(in b, out a, out c) {
 
            }
 
        }
 
    }
 
}
 
\ No newline at end of file
 
}
0 comments (0 inline, 0 general)