package scanner import ( "git.akyoto.dev/cli/q/src/errors" "git.akyoto.dev/cli/q/src/fs" "git.akyoto.dev/cli/q/src/token" "git.akyoto.dev/cli/q/src/types" ) // scanStruct scans a struct. func (s *Scanner) scanStruct(file *fs.File, tokens token.List, i int) (int, error) { i++ if tokens[i].Kind != token.Identifier { return i, errors.New(errors.ExpectedStructName, file, tokens[i].Position) } structName := tokens[i].Text(file.Bytes) structure := types.NewStruct(structName) i++ if tokens[i].Kind != token.BlockStart { return i, errors.New(errors.MissingBlockStart, file, tokens[i].Position) } i++ closed := false for i < len(tokens) { if tokens[i].Kind == token.Identifier { fieldPosition := i fieldName := tokens[i].Text(file.Bytes) i++ fieldTypeName := tokens[i].Text(file.Bytes) fieldType := types.Int switch fieldTypeName { case "Int", "Int64": case "Int32": fieldType = types.Int32 case "Int16": fieldType = types.Int16 case "Int8": fieldType = types.Int8 default: panic("not implemented") } i++ structure.AddField(&types.Field{ Type: fieldType, Name: fieldName, Position: token.Position(fieldPosition), Offset: structure.Size(), }) } if tokens[i].Kind == token.BlockEnd { closed = true break } i++ } if !closed { return i, errors.New(errors.MissingBlockEnd, file, tokens[i].Position) } s.types <- structure return i, nil }