diff --git a/crates/codegen/src/ts.rs b/crates/codegen/src/ts.rs index 0f82b2b..4378415 100644 --- a/crates/codegen/src/ts.rs +++ b/crates/codegen/src/ts.rs @@ -29,7 +29,7 @@ impl Codegen { self.emit(&self.gen_ir(&ir.kind, true)); } - self.emit("f_main();"); + self.emit("_main();"); } fn gen_ir(&self, ir: &IRKind, should_gen_semicolon: bool) -> String { @@ -39,7 +39,7 @@ impl Codegen { match ir { IRKind::Define { public, name, type_hint, value, mutable, .. } => { format!( - "{} {} v_{}: {} = {}{}\n", + "{} {} _{}: {} = {}{}\n", if *public { "export" } else { "" }, if *mutable { "let" } else { "const" }, name, @@ -51,7 +51,7 @@ impl Codegen { IRKind::Call { name, args, .. } => { format!( - "f_{}({}){}", + "_{}({}){}", name, args .iter() @@ -82,11 +82,11 @@ impl Codegen { IRKind::Fun { public, name, return_type_hint, args, body, .. } => { let args = args .iter() - .map(|arg| format!("v_{}: {}", arg.0, arg.1)) + .map(|arg| format!("_{}: {}", arg.0, arg.1)) .collect::>(). join(", "); format!( - "{} const f_{} = ({}): {} => {};\n", + "{} const _{} = ({}): {} => {};\n", if *public { "export" } else { "" }, name, args, @@ -152,7 +152,7 @@ impl Codegen { Value::Int(value) => format!("{}", value), Value::Boolean(value) => format!("{}", value), Value::String(value) => format!("\"{}\"", value), - Value::Ident(value) => format!("v_{}", value), + Value::Ident(value) => format!("_{}", value), } }, diff --git a/crates/hir/src/lib.rs b/crates/hir/src/lib.rs index e7cefe3..254da0d 100644 --- a/crates/hir/src/lib.rs +++ b/crates/hir/src/lib.rs @@ -455,13 +455,23 @@ fn gen_type_hint(type_hint: &Typehint) -> String { _ => t.to_string() }, Typehint::Tuple(ts) => { - let mut types = Vec::new(); - for t in ts { - types.push(gen_type_hint(&t.0)); - } + let types = ts.iter().map(|arg| gen_type_hint(&arg.0)).collect::>(); format!("[{}]", types.join(", ")) }, Typehint::Vector(t) => format!("{}[]", gen_type_hint(&t.0)), - Typehint::Function(_args, _ret) => {dbg!(type_hint); todo!()}, // TODO: Function type + Typehint::Function(args, ret) => { + let args_ty = args.iter().map(|arg| gen_type_hint(&arg.0)).collect::>(); + let return_ty = gen_type_hint(&ret.0); + format!( + "({}) => {}", + args_ty + .iter() + .enumerate() + .map(|(i, arg)| format!("__{}: {}", i, arg)) + .collect::>() + .join(", "), + return_ty + ) + }, } } diff --git a/crates/parser/src/lib.rs b/crates/parser/src/lib.rs index 54617f0..ba09b65 100644 --- a/crates/parser/src/lib.rs +++ b/crates/parser/src/lib.rs @@ -5,49 +5,51 @@ pub mod types; use types::{Expr, Spanned, Typehint}; fn typehint_parser() -> impl Parser, Error = Simple> + Clone { - let single = filter_map(|span, token| match token { - Token::Identifier(s) => Ok((Typehint::Single(s), span)), - _ => Err(Simple::expected_input_found(span, Vec::new(), Some(token))), - }); - - let tuple = single - .separated_by(just(Token::Comma)) - .allow_trailing() - .delimited_by( - just(Token::OpenParen), - just(Token::CloseParen), - ) - .map_with_span(|args, span| { - (Typehint::Tuple(args), span) + recursive(|ty| { + let single = filter_map(|span, token| match token { + Token::Identifier(s) => Ok((Typehint::Single(s), span)), + _ => Err(Simple::expected_input_found(span, Vec::new(), Some(token))), }); - let vector = single - .delimited_by( - just(Token::OpenBracket), - just(Token::CloseBracket), - ) - .map_with_span(|arg, span| { - (Typehint::Vector(Box::new(arg)), span) - }); + let tuple = single + .separated_by(just(Token::Comma)) + .allow_trailing() + .delimited_by( + just(Token::OpenParen), + just(Token::CloseParen), + ) + .map_with_span(|args, span| { + (Typehint::Tuple(args), span) + }); - let function = single - .separated_by(just(Token::Comma)) - .allow_trailing() - .delimited_by( - just(Token::Pipe), - just(Token::Pipe), - ) - .then_ignore(just(Token::Arrow)) - .then(single) - .map_with_span(|(args, ret), span| { - (Typehint::Function(args, Box::new(ret)), span) - }); + let vector = single + .delimited_by( + just(Token::OpenBracket), + just(Token::CloseBracket), + ) + .map_with_span(|arg, span| { + (Typehint::Vector(Box::new(arg)), span) + }); - single - .or(tuple) - .or(vector) - .or(function) - .labelled("type hint") + let function = ty + .separated_by(just(Token::Comma)) + .allow_trailing() + .delimited_by( + just(Token::Pipe), + just(Token::Pipe), + ) + .then_ignore(just(Token::Arrow)) + .then(single) + .map_with_span(|(args, ret), span| { + (Typehint::Function(args, Box::new(ret)), span) + }); + + single + .or(tuple) + .or(vector) + .or(function) + .labelled("type hint") + }) } fn expr_parser() -> impl Parser>, Error = Simple> + Clone { diff --git a/example/tuples.hz b/example/tuples.hz index cba831f..016f342 100644 --- a/example/tuples.hz +++ b/example/tuples.hz @@ -1,6 +1,14 @@ -fun test (foo: int) (bar: int) : int = foo * bar -fun f (fn: |int, int| -> int) (x: int) : int = fn(x) +fun mul (foo: int) (bar: int) : int = foo * bar +fun map + (fn: |int, int| -> int) + (to: int) + : int += fn(to, 10) fun main: void = do - let x : int = 20 -end \ No newline at end of file + let foo : int = 69 + let bar : int = 10 + + map(mul, foo) + |> @write(_) +end