Implemented error messages

This commit is contained in:
Eduard Urbach 2024-06-13 12:13:32 +02:00
parent 423526e567
commit e3b26c79f4
Signed by: eduard
GPG key ID: 49226B848C78F6C8
16 changed files with 362 additions and 60 deletions

View file

@ -8,6 +8,7 @@ import (
"git.akyoto.dev/cli/q/src/build/directory"
"git.akyoto.dev/cli/q/src/build/token"
"git.akyoto.dev/cli/q/src/errors"
)
// Scan scans the directory.
@ -86,46 +87,141 @@ func scanFile(path string, functions chan<- *Function) error {
tokens := token.Tokenize(contents)
var (
i = 0
groupLevel = 0
blockLevel = 0
headerStart = -1
nameStart = -1
paramsStart = -1
bodyStart = -1
)
for i, t := range tokens {
switch t.Kind {
case token.Identifier:
if blockLevel == 0 && groupLevel == 0 {
headerStart = i
for {
// Function name
for i < len(tokens) {
if tokens[i].Kind == token.Identifier {
nameStart = i
i++
break
}
case token.GroupStart:
groupLevel++
case token.GroupEnd:
groupLevel--
case token.BlockStart:
blockLevel++
if blockLevel == 1 {
bodyStart = i
if tokens[i].Kind == token.NewLine {
i++
continue
}
case token.BlockEnd:
blockLevel--
if tokens[i].Kind == token.EOF {
return nil
}
if blockLevel == 0 {
function := &Function{
Name: tokens[headerStart].Text(),
Head: tokens[headerStart:bodyStart],
Body: tokens[bodyStart : i+1],
return errors.New(errors.ExpectedFunctionName, path, tokens, i)
}
// Function parameters
for i < len(tokens) {
if tokens[i].Kind == token.GroupStart {
groupLevel++
if groupLevel == 1 {
paramsStart = i
}
functions <- function
i++
continue
}
}
}
return nil
if tokens[i].Kind == token.GroupEnd {
groupLevel--
if groupLevel < 0 {
return errors.New(errors.MissingGroupStart, path, tokens, i)
}
i++
if groupLevel == 0 {
break
}
continue
}
if tokens[i].Kind == token.EOF {
if groupLevel > 0 {
return errors.New(errors.MissingGroupEnd, path, tokens, i)
}
if paramsStart == -1 {
return errors.New(errors.ExpectedFunctionParameters, path, tokens, i)
}
return nil
}
if groupLevel > 0 {
i++
continue
}
return errors.New(errors.ExpectedFunctionParameters, path, tokens, i)
}
// Function definition
for i < len(tokens) {
if tokens[i].Kind == token.BlockStart {
blockLevel++
if blockLevel == 1 {
bodyStart = i
}
i++
continue
}
if tokens[i].Kind == token.BlockEnd {
blockLevel--
if blockLevel < 0 {
return errors.New(errors.MissingBlockStart, path, tokens, i)
}
i++
if blockLevel == 0 {
break
}
continue
}
if tokens[i].Kind == token.EOF {
if blockLevel > 0 {
return errors.New(errors.MissingBlockEnd, path, tokens, i)
}
if bodyStart == -1 {
return errors.New(errors.ExpectedFunctionDefinition, path, tokens, i)
}
return nil
}
if blockLevel > 0 {
i++
continue
}
return errors.New(errors.ExpectedFunctionDefinition, path, tokens, i)
}
functions <- &Function{
Name: tokens[nameStart].Text(),
Head: tokens[paramsStart:bodyStart],
Body: tokens[bodyStart : i+1],
}
nameStart = -1
paramsStart = -1
bodyStart = -1
}
}