75 lines
1.8 KiB
Go
75 lines
1.8 KiB
Go
package scanner
|
|
|
|
import (
|
|
"os"
|
|
|
|
"git.urbach.dev/cli/q/src/errors"
|
|
"git.urbach.dev/cli/q/src/fs"
|
|
"git.urbach.dev/cli/q/src/token"
|
|
)
|
|
|
|
// scanFile scans a single file.
|
|
func (s *Scanner) scanFile(path string, pkg string) error {
|
|
contents, err := os.ReadFile(path)
|
|
|
|
if err != nil {
|
|
return err
|
|
}
|
|
|
|
tokens := token.Tokenize(contents)
|
|
|
|
file := &fs.File{
|
|
Path: path,
|
|
Bytes: contents,
|
|
Tokens: tokens,
|
|
Package: pkg,
|
|
}
|
|
|
|
s.files <- file
|
|
|
|
for i := 0; i < len(tokens); i++ {
|
|
switch tokens[i].Kind {
|
|
case token.NewLine:
|
|
case token.Comment:
|
|
case token.Identifier:
|
|
if i+1 >= len(tokens) {
|
|
return errors.New(errors.InvalidDefinition, file, tokens[i].End())
|
|
}
|
|
|
|
next := tokens[i+1]
|
|
|
|
switch next.Kind {
|
|
case token.GroupStart:
|
|
i, err = s.scanFunction(file, tokens, i)
|
|
case token.BlockStart:
|
|
i, err = s.scanStruct(file, tokens, i)
|
|
case token.GroupEnd:
|
|
return errors.New(errors.MissingGroupStart, file, next.Position)
|
|
case token.BlockEnd:
|
|
return errors.New(errors.MissingBlockStart, file, next.Position)
|
|
case token.Invalid:
|
|
return errors.New(&errors.InvalidCharacter{Character: next.Text(file.Bytes)}, file, next.Position)
|
|
default:
|
|
return errors.New(errors.InvalidDefinition, file, next.Position)
|
|
}
|
|
case token.Import:
|
|
i, err = s.scanImport(file, tokens, i)
|
|
case token.Extern:
|
|
i, err = s.scanExtern(file, tokens, i)
|
|
case token.Const:
|
|
i, err = s.scanConst(file, tokens, i)
|
|
case token.EOF:
|
|
return nil
|
|
case token.Invalid:
|
|
return errors.New(&errors.InvalidCharacter{Character: tokens[i].Text(file.Bytes)}, file, tokens[i].Position)
|
|
default:
|
|
return errors.New(&errors.InvalidInstruction{Instruction: tokens[i].Text(file.Bytes)}, file, tokens[i].Position)
|
|
}
|
|
|
|
if err != nil {
|
|
return err
|
|
}
|
|
}
|
|
|
|
return nil
|
|
}
|