diff --git a/parser/src/grammar.pest b/parser/src/grammar.pest index 4cc1a94..40d5351 100644 --- a/parser/src/grammar.pest +++ b/parser/src/grammar.pest @@ -17,19 +17,19 @@ top_level = _{ import | function_decl | struct_decl | package } package = { "package" ~ identifier ~ ";" } -export = { "export" } +export = { "public" } import = { "import" ~ string_lit ~ ";" } param_list = { param ~ ("," ~ param)* ~ ","? } -param = { export? ~ identifier ~ ":" ~ type_expr } +param = { export? ~ type_expr ~ identifier } struct_decl = { export? ~ "struct" ~ identifier ~ "{" ~ param_list? ~ "}" } function_decl = { - export? ~ "function" ~ identifier ~ "(" ~ param_list? ~ ")" ~ (":" ~ type_expr)? ~ block + export? ~ type_expr ~ identifier ~ "(" ~ param_list? ~ ")" ~ block } // ================= STATEMENTS ================= diff --git a/parser/src/lib.rs b/parser/src/lib.rs index 1d29ba5..fb8e1ea 100644 --- a/parser/src/lib.rs +++ b/parser/src/lib.rs @@ -29,16 +29,22 @@ pub fn parse(source: &str) -> Result, ParseError> { Ok(statements) } -impl From> for TypeExpr { - fn from(pair: pest::iterators::Pair) -> Self { - match pair.as_rule() { +impl TryFrom> for TypeExpr { + type Error = (); + + fn try_from(pair: pest::iterators::Pair<'_, Rule>) -> Result { + if pair.as_str() == "void" { + return Err(()); + } + + Ok(match pair.as_rule() { Rule::type_expr => { let inner = pair.into_inner().next().unwrap(); - TypeExpr::from(inner) + TypeExpr::try_from(inner)? } Rule::identifier => TypeExpr::Identifier(pair.as_str().to_string()), _ => unimplemented!("TypeExpr parsing not implemented yet"), - } + }) } } @@ -55,8 +61,8 @@ impl From<(bool, pest::iterators::Pair<'_, Rule>)> for ParamList { } else { false }; + let param_type = TypeExpr::try_from(param_inner.next().unwrap()).unwrap(); let param_name = param_inner.next().unwrap().as_str().to_string(); - let param_type = TypeExpr::from(param_inner.next().unwrap()); (param_name, (export, param_type)) }) .collect(); @@ -90,15 +96,10 @@ impl TryFrom> for TopLevel { } else { false }; - let name = inner.next().unwrap().as_str().to_string(); - let params = if inner.peek().unwrap().as_rule() == Rule::param_list { - ParamList::from((false, inner.next().unwrap())) - } else { - ParamList(HashMap::new()) - }; + let return_type = if let Some(next) = inner.peek() { if next.as_rule() == Rule::type_expr { - Some(TypeExpr::from(inner.next().unwrap())) + TypeExpr::try_from(inner.next().unwrap()).ok() } else { None } @@ -106,6 +107,13 @@ impl TryFrom> for TopLevel { None }; + let name = inner.next().unwrap().as_str().to_string(); + let params = if inner.peek().unwrap().as_rule() == Rule::param_list { + ParamList::from((false, inner.next().unwrap())) + } else { + ParamList(HashMap::new()) + }; + let body = Block::from(inner.next().unwrap()); Ok(TopLevel::FunctionDecl { diff --git a/test/mist.json b/test/mist.json index 6a2d242..104ad8f 100644 --- a/test/mist.json +++ b/test/mist.json @@ -1,5 +1,5 @@ { "entry": "src/main.ms", "out_dir": "build", - "script": true + "script": false } \ No newline at end of file diff --git a/test/src/main.ms b/test/src/main.ms index 0fc1fcc..e1170da 100644 --- a/test/src/main.ms +++ b/test/src/main.ms @@ -2,21 +2,10 @@ package main; import "fmt"; -function main() { - doSomething(); - let a = doSomethingElse(); - - if (a + 1 == 67 + 1) { - fmt.println(a); - } +void main() { + test(67); } -function doSomething() { - fmt.println("hello"); -} - -function doSomethingElse(): int { - fmt.println("world"); - - return 67; +void test(int x) { + fmt.println("Hello" + x); }