Browse Source

add SectionValue.Resolve

pull/16/head
Brett Langdon 11 years ago
parent
commit
6b23201a93
2 changed files with 48 additions and 47 deletions
  1. +37
    -1
      config/section.go
  2. +11
    -46
      parser/parser.go

+ 37
- 1
config/section.go View File

@ -1,6 +1,11 @@
package config package config
import "encoding/json"
import (
"encoding/json"
"errors"
"fmt"
"strings"
)
type SectionValue struct { type SectionValue struct {
Name string Name string
@ -70,6 +75,37 @@ func (this *SectionValue) Contains(name string) bool {
return ok return ok
} }
func (this *SectionValue) Resolve(setting string) (ConfigValue, error) {
parts := strings.Split(setting, ".")
var reference ConfigValue
reference = this
visited := []string{}
for {
if len(parts) == 0 {
break
}
if reference.GetType() != SECTION {
name := strings.Join(visited, ".")
return nil, errors.New(fmt.Sprintf("'%s' is a %s not a SECTION", name, reference.GetType()))
}
part := parts[0]
parts = parts[1:]
section := reference.(*SectionValue)
if section.Contains(part) == false {
name := strings.Join(visited, ".")
if len(name) > 0 {
return nil, errors.New(fmt.Sprintf("'%s' does not have setting '%s'", name, part))
} else {
return nil, errors.New(fmt.Sprintf("setting '%s' does not exist", part))
}
}
reference = section.Get(part)
visited = append(visited, part)
}
return reference, nil
}
func (this *SectionValue) ToJSON() ([]byte, error) { func (this *SectionValue) ToJSON() ([]byte, error) {
data, err := this.ToMap() data, err := this.ToMap()
if err != nil { if err != nil {


+ 11
- 46
parser/parser.go View File

@ -7,7 +7,6 @@ import (
"os" "os"
"path/filepath" "path/filepath"
"strconv" "strconv"
"strings"
"github.com/brettlangdon/forge/config" "github.com/brettlangdon/forge/config"
"github.com/brettlangdon/forge/token" "github.com/brettlangdon/forge/token"
@ -31,43 +30,25 @@ func (this *Parser) SyntaxError(msg string) error {
return errors.New(msg) return errors.New(msg)
} }
func (this *Parser) ReferenceTypeError(names []string, expected config.ConfigType, actual config.ConfigType) error {
reference := strings.Join(names, ".")
msg := fmt.Sprintf(
"Reference type error, '%s', expected type %s instead got %s",
reference,
expected,
actual,
)
return errors.New(msg)
}
func (this *Parser) ReferenceMissingError(names []string, searching string) error {
reference := strings.Join(names, ".")
msg := fmt.Sprintf(
"Reference missing error, '%s' does not have key '%s'",
reference,
searching,
)
return errors.New(msg)
}
func (this *Parser) readToken() token.Token { func (this *Parser) readToken() token.Token {
this.cur_tok = this.tokenizer.NextToken() this.cur_tok = this.tokenizer.NextToken()
return this.cur_tok return this.cur_tok
} }
func (this *Parser) parseReference(starting_section *config.SectionValue, period bool) (config.ConfigValue, error) { func (this *Parser) parseReference(starting_section *config.SectionValue, period bool) (config.ConfigValue, error) {
names := []string{}
name := ""
if period == false { if period == false {
names = append(names, this.cur_tok.Literal)
name = this.cur_tok.Literal
} }
for { for {
this.readToken() this.readToken()
if this.cur_tok.ID == token.PERIOD && period == false { if this.cur_tok.ID == token.PERIOD && period == false {
period = true period = true
} else if period && this.cur_tok.ID == token.IDENTIFIER { } else if period && this.cur_tok.ID == token.IDENTIFIER {
names = append(names, this.cur_tok.Literal)
if len(name) > 0 {
name += "."
}
name += this.cur_tok.Literal
period = false period = false
} else if this.cur_tok.ID == token.SEMICOLON { } else if this.cur_tok.ID == token.SEMICOLON {
break break
@ -76,7 +57,7 @@ func (this *Parser) parseReference(starting_section *config.SectionValue, period
return nil, this.SyntaxError(msg) return nil, this.SyntaxError(msg)
} }
} }
if len(names) == 0 {
if len(name) == 0 {
return nil, this.SyntaxError( return nil, this.SyntaxError(
fmt.Sprintf("expected IDENTIFIER instead found %s", this.cur_tok.Literal), fmt.Sprintf("expected IDENTIFIER instead found %s", this.cur_tok.Literal),
) )
@ -86,27 +67,11 @@ func (this *Parser) parseReference(starting_section *config.SectionValue, period
return nil, this.SyntaxError(fmt.Sprintf("expected IDENTIFIER after PERIOD")) return nil, this.SyntaxError(fmt.Sprintf("expected IDENTIFIER after PERIOD"))
} }
var reference config.ConfigValue
reference = starting_section
visited := []string{}
for {
if len(names) == 0 {
break
}
if reference.GetType() != config.SECTION {
return nil, this.ReferenceTypeError(visited, config.SECTION, reference.GetType())
}
name := names[0]
names = names[1:]
section := reference.(*config.SectionValue)
if section.Contains(name) == false {
return nil, this.ReferenceMissingError(visited, name)
}
reference = section.Get(name)
visited = append(visited, name)
value, err := starting_section.Resolve(name)
if err != nil {
err = errors.New("Reference error, " + err.Error())
} }
return reference, nil
return value, err
} }
func (this *Parser) parseSetting(name string) error { func (this *Parser) parseSetting(name string) error {


Loading…
Cancel
Save