1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
pub mod parser;

use intuicio_core::{crate_version, script::BytesContentParser, IntuicioVersion};
use intuicio_frontend_serde::*;
use std::error::Error;

pub type AsmScript = SerdeScript;
pub type AsmLiteral = SerdeLiteral;
pub type AsmExpression = SerdeExpression;
pub type AsmOperation = SerdeOperation;
pub type AsmFunctionParameter = SerdeFunctionParameter;
pub type AsmFunction = SerdeFunction;
pub type AsmStructField = SerdeStructField;
pub type AsmStruct = SerdeStruct;
pub type AsmModule = SerdeModule;
pub type AsmFile = SerdeFile;
pub type AsmPackage = SerdePackage;
pub type AsmNodeTypeInfo = SerdeNodeTypeInfo;
pub type AsmNodes = SerdeNodes;
pub type CompileAsmNodeGraphVisitor = CompileSerdeNodeGraphVisitor;

pub fn frontend_assembly_version() -> IntuicioVersion {
    crate_version!()
}

pub struct AsmContentParser;

impl BytesContentParser<SerdeFile> for AsmContentParser {
    fn parse(&self, bytes: Vec<u8>) -> Result<SerdeFile, Box<dyn Error>> {
        let content = String::from_utf8(bytes)?;
        Ok(parser::parse(&content)?)
    }
}

#[cfg(test)]
mod tests {
    use crate::*;
    use intuicio_backend_vm::prelude::*;
    use intuicio_core::prelude::*;

    #[test]
    fn test_frontend_asm() {
        let mut registry = Registry::default().with_basic_types();
        registry.add_function(define_function! {
            registry => mod intrinsics fn add(a: usize, b: usize) -> (result: usize) {
                (a + b,)
            }
        });
        let mut content_provider = FileContentProvider::new("iasm", AsmContentParser);
        AsmPackage::new("../../resources/package.iasm", &mut content_provider)
            .unwrap()
            .compile()
            .install::<VmScope<AsmExpression>>(
                &mut registry,
                None,
                // Some(
                //     PrintDebugger::full()
                //         .basic_printables()
                //         .stack_bytes(false)
                //         .registers_bytes(false)
                //         .into_handle(),
                // ),
            );
        assert!(registry
            .find_function(FunctionQuery {
                name: Some("main".into()),
                module_name: Some("test".into()),
                ..Default::default()
            })
            .is_some());
        let mut host = Host::new(
            Context::new(1024, 1024, 1024),
            RegistryHandle::new(registry),
        );
        let (result,) = host
            .call_function::<(usize,), _>("main", "test", None)
            .unwrap()
            .run(());
        assert_eq!(result, 42);
    }
}