loader.go 1.2 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950
  1. package compiler
  2. import (
  3. "fmt"
  4. "strings"
  5. "kumachan/standalone/util/richtext"
  6. "kumachan/lang/source"
  7. "kumachan/lang/textual/ast"
  8. "kumachan/lang/textual/syntax"
  9. "kumachan/lang/textual/parser"
  10. "kumachan/lang/textual/transformer"
  11. )
  12. const SourceFilenameSuffix = ".km"
  13. type Loader struct {
  14. Suffix string
  15. Load func(bytes ([] byte), key source.FileKey) (*ast.Root, richtext.Error)
  16. }
  17. var loaders = [] Loader {{
  18. Suffix: SourceFilenameSuffix,
  19. Load: func(content ([] byte), key source.FileKey) (*ast.Root, richtext.Error) {
  20. var code = source.DecodeUtf8ToCode(content)
  21. var name = key.String()
  22. var root = syntax.DefaultRoot()
  23. var cst_, err = parser.Parse(code, root, name)
  24. if err != nil { return nil, err }
  25. var ast_ = transformer.Transform(cst_, key).(ast.Root)
  26. return &ast_, nil
  27. },
  28. }}
  29. func Load(file string, fs FileSystem) (*ast.Root, richtext.Error) {
  30. var key = source.FileKey {
  31. Context: fs.Key(),
  32. Path: file,
  33. }
  34. for _, l := range loaders {
  35. if strings.HasSuffix(file, l.Suffix) {
  36. var content, err = ReadFile(file, fs)
  37. if err != nil { return nil, richtext.ErrorFrom(err) }
  38. return l.Load(content, key)
  39. }
  40. }
  41. var err = fmt.Errorf("no loader available for file \"%s\"", key)
  42. return nil, richtext.ErrorFrom(err)
  43. }