Skip to content

Commit

Permalink
[PARSER] Parse decorators argument conditionally, better error messag…
Browse files Browse the repository at this point in the history
…e for `if` false calling
  • Loading branch information
PeyTy committed Jul 11, 2024
1 parent 2629f2a commit a7ab332
Show file tree
Hide file tree
Showing 2 changed files with 31 additions and 20 deletions.
49 changes: 29 additions & 20 deletions source/compiler/parser.hexa
Original file line number Diff line number Diff line change
Expand Up @@ -612,6 +612,12 @@ class Parser {
let temp = i
i = eifAt
failHint('`if` body must be a `{` block `}`')
switch eif {
case Call(_, args):
// TODO at args[0] if present
// TODO same for `[`
failHint('Seems like you have `()` after `{` block `}` like `}(`')
}
i = temp
}
}
Expand Down Expand Up @@ -1689,22 +1695,30 @@ class Parser {
let token = tok()

// TODO drop support for type-level decorators
if token == Token.At {
// TODO soft parsing error
i++
let name = print() // TODO `getgo(Token.Identifier)`
// TODO `failHintAt` but consume decorator first with `parserDec` cause may have parameters
i--
// TODO should know if it `var`, `let` or function argument
fail("Decorators should be placed at variable's declaration like `@\(name) var \(varName)` instead of their type.")
// TODO it may happen that decorator is applied to next var if current is type-less
// ^ recommend `///` to split expressions
}
// if token == Token.At {
// // TODO soft parsing error
// i++
// let name = print() // TODO `getgo(Token.Identifier)`
// // TODO `failHintAt` but consume decorator first with `parserDec` cause may have parameters
// i--
// // TODO should know if it `var`, `let` or function argument
// fail("Decorators should be placed at variable's declaration like `@\(name) var \(varName)` instead of their type.")
// // TODO it may happen that decorator is applied to next var if current is type-less
// // ^ recommend `///` to split expressions
// }

// TODO reuse in inline function `fun isStartOfType(token)`
// ^ to be used in [[parseFunction]]
if
// token == Token.Colon or // `: T`
(
token == Token.At and (
// `var name <single space here> @decorator Type`
// TODO add `lastToken*`
// TODO proper error for `+ 0` when no space
lex.column[i] == lex.value[i - 1].length + lex.column[i - 1] + 1
)
) or
token == Token.IndexOpen or // `[T]` TODO rename `B?Open` to `ArrayOpen`
token == Token.BlockOpen or // `{v:T}` TODO `interface {v:T}` or disallow entirely?
// TODO rename `B?Open` to `BlockOpen` `BodyOpen` `GroupOpen`
Expand Down Expand Up @@ -1885,20 +1899,14 @@ class Parser {
}

// TODO well `tok()` could be just `@inline let token { get }` or something
if tok() == Token.At {
i++
let decName = print() // TODO `getgo(Token.Identifier)` + `failHintAt`
i--
fail("Decorators should be placed at argument's declaration like `@\(decName) \(name)` instead of their type.")
}

let token = tok()

if
// Note: don't do it like that! Some type syntax uses lowercases
//tok() != Token.Assign and
//tok() != Token.CallClose and
//tok() != Token.Comma
token == Token.At or
token == Token.IndexOpen or
token == Token.BlockOpen or
token == Token.Title or
Expand Down Expand Up @@ -2149,7 +2157,8 @@ class Parser {
i++
let name = getgo(Token.Identifier)
let values = []
if tok() == Token.CallOpen {
// `@name/*no space here*/(args)`
if tok() == Token.CallOpen and (lex.column[i] == lex.value[i - 1].length + lex.column[i - 1]) {
i++
if tok() != Token.CallClose { while true {
values.push(parseExpr())
Expand Down Expand Up @@ -2203,7 +2212,7 @@ class Parser {
return NodeType.String(getgo(Token.QuotedString))
}

if (tok() == Token.Identifier && offset(1) == Token.CallOpen) {
if tok() == Token.Identifier and offset(1) == Token.CallOpen {
let name = getgo(Token.Identifier)
i++
let argNames: [String] = []
Expand Down
2 changes: 2 additions & 0 deletions source/compiler/typer.hexa
Original file line number Diff line number Diff line change
Expand Up @@ -38,10 +38,12 @@ class Typer {
fun checkOverrides(info: Module, name: String, e: Node) {
if info.exported.has(name) {
fail('Module `\(info.path)` already exports name `\(name)`', e)
// TODO where?
}

if info.imported.has(name) {
fail('Module `\(info.path)` already imports name `\(name)`', e)
// TODO where?
}
}

Expand Down

0 comments on commit a7ab332

Please sign in to comment.