function as argument success

pull/4/head
Natapat Samutpong 2022-04-09 20:52:00 +07:00
parent c095efdd7c
commit 1cbb2a6f9a
4 changed files with 74 additions and 54 deletions

View File

@ -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::<Vec<_>>().
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),
}
},

View File

@ -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::<Vec<_>>();
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::<Vec<_>>();
let return_ty = gen_type_hint(&ret.0);
format!(
"({}) => {}",
args_ty
.iter()
.enumerate()
.map(|(i, arg)| format!("__{}: {}", i, arg))
.collect::<Vec<_>>()
.join(", "),
return_ty
)
},
}
}

View File

@ -5,49 +5,51 @@ pub mod types;
use types::{Expr, Spanned, Typehint};
fn typehint_parser() -> impl Parser<Token, Spanned<Typehint>, Error = Simple<Token>> + 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<Token, Vec<Spanned<Expr>>, Error = Simple<Token>> + Clone {

View File

@ -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
let foo : int = 69
let bar : int = 10
map(mul, foo)
|> @write(_)
end