From 4793c4eb69c7e808b1ba05a995f37feaa0b1e465 Mon Sep 17 00:00:00 2001 From: Dennis Ranke Date: Wed, 3 Nov 2021 22:07:55 +0100 Subject: [PATCH] added support for function imports --- Cargo.lock | 22 ++++++++++---------- Cargo.toml | 2 +- plasma.cwa | 16 +++++++++++++++ src/ast.rs | 2 +- src/emit.rs | 36 +++++++++++++++++++++++++++------ src/parser.rs | 20 +++++++++++++++++- src/typecheck.rs | 24 +++++++++++++++++++++- trainride.hw => trainride.cwa | 0 uw8loader.hw => uw8loader.cwa | 0 warptunnel.hw => warptunnel.cwa | 0 xorscroll.hw => xorscroll.cwa | 0 11 files changed, 101 insertions(+), 21 deletions(-) create mode 100644 plasma.cwa rename trainride.hw => trainride.cwa (100%) rename uw8loader.hw => uw8loader.cwa (100%) rename warptunnel.hw => warptunnel.cwa (100%) rename xorscroll.hw => xorscroll.cwa (100%) diff --git a/Cargo.lock b/Cargo.lock index f786bd9..548f5a7 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -69,6 +69,17 @@ version = "0.2.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "7a81dae078cea95a014a339291cec439d2f232ebe854a9d672b796c6afafa9b7" +[[package]] +name = "curlywas" +version = "0.1.0" +dependencies = [ + "anyhow", + "ariadne", + "chumsky", + "wasm-encoder", + "wasmparser", +] + [[package]] name = "getrandom" version = "0.2.3" @@ -80,17 +91,6 @@ dependencies = [ "wasi", ] -[[package]] -name = "hwas" -version = "0.1.0" -dependencies = [ - "anyhow", - "ariadne", - "chumsky", - "wasm-encoder", - "wasmparser", -] - [[package]] name = "lazy_static" version = "1.4.0" diff --git a/Cargo.toml b/Cargo.toml index bb2a6af..54c1a1b 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -1,5 +1,5 @@ [package] -name = "hwas" +name = "curlywas" version = "0.1.0" edition = "2021" diff --git a/plasma.cwa b/plasma.cwa new file mode 100644 index 0000000..5f20aa2 --- /dev/null +++ b/plasma.cwa @@ -0,0 +1,16 @@ +import "env.memory" memory(4); +import "math.sin" fn sin(f32) -> f32; +import "math.cos" fn cos(f32) -> f32; + +export fn tic(time: i32) { + let i: i32; + loop screen { + let x = (i % 320) as f32 / 48 as f32; + let y = (i / 320) as f32 / 48 as f32; + let t = time as f32 / 200 as f32; + + i?120 = (sin(x + t) * 32 as f32) as i32 + 128; + + branch_if (i := i + 1) < 320*256: screen + } +} \ No newline at end of file diff --git a/src/ast.rs b/src/ast.rs index 96018a3..0344f86 100644 --- a/src/ast.rs +++ b/src/ast.rs @@ -29,7 +29,7 @@ pub enum ImportType { type_: Type, mutable: bool, }, - // Function { name: String, params: Vec, result: Option } + Function { name: String, params: Vec, result: Option } } #[derive(Debug)] diff --git a/src/emit.rs b/src/emit.rs index b172b61..4e3167e 100644 --- a/src/emit.rs +++ b/src/emit.rs @@ -24,6 +24,7 @@ pub fn emit(script: &ast::Script) -> Vec { } let mut globals: HashMap<&str, u32> = HashMap::new(); + let mut function_map = HashMap::new(); { let mut imports = ImportSection::new(); @@ -56,6 +57,18 @@ pub fn emit(script: &ast::Script) -> Vec { } .into() } + ast::ImportType::Function { + ref name, + ref params, + ref result, + } => { + function_map.insert(name.clone(), function_map.len() as u32); + EntityType::Function( + *function_types + .get(&(params.clone(), result.clone())) + .unwrap() as u32, + ) + } }; imports.import(module, name, type_); } @@ -68,16 +81,15 @@ pub fn emit(script: &ast::Script) -> Vec { let mut exports = ExportSection::new(); let mut code = CodeSection::new(); - let mut function_map = HashMap::new(); for func in script.functions.iter() { function_map.insert(func.name.clone(), function_map.len() as u32); } - for (index, func) in script.functions.iter().enumerate() { + for func in script.functions.iter() { let type_ = *function_types.get(&function_type_key(func)).unwrap(); functions.function(type_ as u32); if func.export { - exports.export(&func.name, Export::Function(index as u32)); + exports.export(&func.name, Export::Function(*function_map.get(&func.name).unwrap() as u32)); } code.function(&emit_function(func, &globals, &function_map)); @@ -96,11 +108,23 @@ type FunctionTypeKey = (Vec, Option); fn collect_function_types(script: &ast::Script) -> HashMap { let mut types: HashMap = HashMap::new(); + for import in &script.imports { + if let ast::ImportType::Function { + ref params, + ref result, + .. + } = import.type_ + { + let index = types.len(); + types + .entry((params.clone(), result.clone())) + .or_insert(index); + } + } + for func in &script.functions { let index = types.len(); - types - .entry(function_type_key(func)) - .or_insert_with(|| index); + types.entry(function_type_key(func)).or_insert(index); } types diff --git a/src/parser.rs b/src/parser.rs index 355e2e8..7437b0f 100644 --- a/src/parser.rs +++ b/src/parser.rs @@ -706,9 +706,27 @@ fn top_level_item_parser() -> impl Parser".to_string())) + .ignore_then(type_parser()) + .or_not(), + ) + .map(|((name, params), result)| ast::ImportType::Function { + name, + params, + result, + }); + let import = just(Token::Import) .ignore_then(string) - .then(import_memory.or(import_global)) + .then(import_memory.or(import_global).or(import_function)) .then_ignore(just(Token::Ctrl(';'))) .map_with_span(|(import, type_), span| { ast::TopLevelItem::Import(ast::Import { diff --git a/src/typecheck.rs b/src/typecheck.rs index a80670e..3f09edd 100644 --- a/src/typecheck.rs +++ b/src/typecheck.rs @@ -47,7 +47,29 @@ pub fn tc_script(script: &mut ast::Script, source: &str) -> Result<()> { ); } } - // ast::ImportType::Function { .. } => todo!(), + ast::ImportType::Function { + ref name, + ref params, + result: ref result_type, + } => { + if let Some(fnc) = context.functions.get(name) { + result = report_duplicate_definition( + "Function already defined", + &import.span, + &fnc.span, + source, + ); + } else { + context.functions.insert( + name.clone(), + FunctionType { + span: import.span.clone(), + params: params.clone(), + type_: *result_type, + }, + ); + } + } ast::ImportType::Memory(..) => (), } } diff --git a/trainride.hw b/trainride.cwa similarity index 100% rename from trainride.hw rename to trainride.cwa diff --git a/uw8loader.hw b/uw8loader.cwa similarity index 100% rename from uw8loader.hw rename to uw8loader.cwa diff --git a/warptunnel.hw b/warptunnel.cwa similarity index 100% rename from warptunnel.hw rename to warptunnel.cwa diff --git a/xorscroll.hw b/xorscroll.cwa similarity index 100% rename from xorscroll.hw rename to xorscroll.cwa