mirror of
https://github.com/exoticorn/curlywas.git
synced 2026-01-20 11:46:43 +01:00
added support for function imports
This commit is contained in:
22
Cargo.lock
generated
22
Cargo.lock
generated
@@ -69,6 +69,17 @@ version = "0.2.2"
|
|||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "7a81dae078cea95a014a339291cec439d2f232ebe854a9d672b796c6afafa9b7"
|
checksum = "7a81dae078cea95a014a339291cec439d2f232ebe854a9d672b796c6afafa9b7"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "curlywas"
|
||||||
|
version = "0.1.0"
|
||||||
|
dependencies = [
|
||||||
|
"anyhow",
|
||||||
|
"ariadne",
|
||||||
|
"chumsky",
|
||||||
|
"wasm-encoder",
|
||||||
|
"wasmparser",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "getrandom"
|
name = "getrandom"
|
||||||
version = "0.2.3"
|
version = "0.2.3"
|
||||||
@@ -80,17 +91,6 @@ dependencies = [
|
|||||||
"wasi",
|
"wasi",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "hwas"
|
|
||||||
version = "0.1.0"
|
|
||||||
dependencies = [
|
|
||||||
"anyhow",
|
|
||||||
"ariadne",
|
|
||||||
"chumsky",
|
|
||||||
"wasm-encoder",
|
|
||||||
"wasmparser",
|
|
||||||
]
|
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "lazy_static"
|
name = "lazy_static"
|
||||||
version = "1.4.0"
|
version = "1.4.0"
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
[package]
|
[package]
|
||||||
name = "hwas"
|
name = "curlywas"
|
||||||
version = "0.1.0"
|
version = "0.1.0"
|
||||||
edition = "2021"
|
edition = "2021"
|
||||||
|
|
||||||
|
|||||||
16
plasma.cwa
Normal file
16
plasma.cwa
Normal file
@@ -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
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -29,7 +29,7 @@ pub enum ImportType {
|
|||||||
type_: Type,
|
type_: Type,
|
||||||
mutable: bool,
|
mutable: bool,
|
||||||
},
|
},
|
||||||
// Function { name: String, params: Vec<Type>, result: Option<Type> }
|
Function { name: String, params: Vec<Type>, result: Option<Type> }
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Debug)]
|
#[derive(Debug)]
|
||||||
|
|||||||
36
src/emit.rs
36
src/emit.rs
@@ -24,6 +24,7 @@ pub fn emit(script: &ast::Script) -> Vec<u8> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
let mut globals: HashMap<&str, u32> = HashMap::new();
|
let mut globals: HashMap<&str, u32> = HashMap::new();
|
||||||
|
let mut function_map = HashMap::new();
|
||||||
|
|
||||||
{
|
{
|
||||||
let mut imports = ImportSection::new();
|
let mut imports = ImportSection::new();
|
||||||
@@ -56,6 +57,18 @@ pub fn emit(script: &ast::Script) -> Vec<u8> {
|
|||||||
}
|
}
|
||||||
.into()
|
.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_);
|
imports.import(module, name, type_);
|
||||||
}
|
}
|
||||||
@@ -68,16 +81,15 @@ pub fn emit(script: &ast::Script) -> Vec<u8> {
|
|||||||
let mut exports = ExportSection::new();
|
let mut exports = ExportSection::new();
|
||||||
let mut code = CodeSection::new();
|
let mut code = CodeSection::new();
|
||||||
|
|
||||||
let mut function_map = HashMap::new();
|
|
||||||
for func in script.functions.iter() {
|
for func in script.functions.iter() {
|
||||||
function_map.insert(func.name.clone(), function_map.len() as u32);
|
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();
|
let type_ = *function_types.get(&function_type_key(func)).unwrap();
|
||||||
functions.function(type_ as u32);
|
functions.function(type_ as u32);
|
||||||
if func.export {
|
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));
|
code.function(&emit_function(func, &globals, &function_map));
|
||||||
@@ -96,11 +108,23 @@ type FunctionTypeKey = (Vec<ast::Type>, Option<ast::Type>);
|
|||||||
fn collect_function_types(script: &ast::Script) -> HashMap<FunctionTypeKey, usize> {
|
fn collect_function_types(script: &ast::Script) -> HashMap<FunctionTypeKey, usize> {
|
||||||
let mut types: HashMap<FunctionTypeKey, usize> = HashMap::new();
|
let mut types: HashMap<FunctionTypeKey, usize> = HashMap::new();
|
||||||
|
|
||||||
for func in &script.functions {
|
for import in &script.imports {
|
||||||
|
if let ast::ImportType::Function {
|
||||||
|
ref params,
|
||||||
|
ref result,
|
||||||
|
..
|
||||||
|
} = import.type_
|
||||||
|
{
|
||||||
let index = types.len();
|
let index = types.len();
|
||||||
types
|
types
|
||||||
.entry(function_type_key(func))
|
.entry((params.clone(), result.clone()))
|
||||||
.or_insert_with(|| index);
|
.or_insert(index);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
for func in &script.functions {
|
||||||
|
let index = types.len();
|
||||||
|
types.entry(function_type_key(func)).or_insert(index);
|
||||||
}
|
}
|
||||||
|
|
||||||
types
|
types
|
||||||
|
|||||||
@@ -706,9 +706,27 @@ fn top_level_item_parser() -> impl Parser<Token, ast::TopLevelItem, Error = Simp
|
|||||||
type_,
|
type_,
|
||||||
});
|
});
|
||||||
|
|
||||||
|
let import_function = just(Token::Fn)
|
||||||
|
.ignore_then(identifier.clone())
|
||||||
|
.then(
|
||||||
|
type_parser()
|
||||||
|
.separated_by(just(Token::Ctrl(',')))
|
||||||
|
.delimited_by(Token::Ctrl('('), Token::Ctrl(')')),
|
||||||
|
)
|
||||||
|
.then(
|
||||||
|
just(Token::Op("->".to_string()))
|
||||||
|
.ignore_then(type_parser())
|
||||||
|
.or_not(),
|
||||||
|
)
|
||||||
|
.map(|((name, params), result)| ast::ImportType::Function {
|
||||||
|
name,
|
||||||
|
params,
|
||||||
|
result,
|
||||||
|
});
|
||||||
|
|
||||||
let import = just(Token::Import)
|
let import = just(Token::Import)
|
||||||
.ignore_then(string)
|
.ignore_then(string)
|
||||||
.then(import_memory.or(import_global))
|
.then(import_memory.or(import_global).or(import_function))
|
||||||
.then_ignore(just(Token::Ctrl(';')))
|
.then_ignore(just(Token::Ctrl(';')))
|
||||||
.map_with_span(|(import, type_), span| {
|
.map_with_span(|(import, type_), span| {
|
||||||
ast::TopLevelItem::Import(ast::Import {
|
ast::TopLevelItem::Import(ast::Import {
|
||||||
|
|||||||
@@ -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(..) => (),
|
ast::ImportType::Memory(..) => (),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user