keyword.go 4.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144
  1. package muesli
  2. import "fmt"
  3. /* Muesli has no key words by default, but they can be defined if desired
  4. * for ease of use. A key word is replaced by a token during lexing. */
  5. type Keyword struct {
  6. Name string
  7. TokenKind
  8. Value
  9. }
  10. var DefaultKeywords []*Keyword = []*Keyword{
  11. &Keyword { "true", TokenKindBoolean, TrueValue },
  12. &Keyword { "false", TokenKindBoolean, FalseValue },
  13. &Keyword { "nil", TokenKindNil, NilValue },
  14. &Keyword { "do", TokenKindOpenBlock, StringValue("{") },
  15. &Keyword { "end", TokenKindCloseBlock, StringValue("}") },
  16. &Keyword { "as", TokenKindOpenParen, StringValue("(") },
  17. &Keyword { "so", TokenKindCloseParen, StringValue(")") },
  18. &Keyword { "list", TokenKindOpenList, StringValue("[") },
  19. &Keyword { "done", TokenKindCloseList, StringValue("]") },
  20. &Keyword { "the", TokenKindGet, StringValue("$") },
  21. &Keyword { "a", TokenKindGet, StringValue("$") },
  22. &Keyword { "an", TokenKindGet, StringValue("$") },
  23. }
  24. var DefaultKeywordsFR []*Keyword = []*Keyword{
  25. &Keyword { "vrai", TokenKindBoolean, TrueValue },
  26. &Keyword { "faux", TokenKindBoolean, FalseValue },
  27. &Keyword { "nul", TokenKindNil, NilValue },
  28. &Keyword { "fais", TokenKindOpenBlock, StringValue("{") },
  29. &Keyword { "fin", TokenKindCloseBlock, StringValue("}") },
  30. &Keyword { "comme", TokenKindOpenParen, StringValue("(") },
  31. &Keyword { "ça", TokenKindCloseParen, StringValue(")") },
  32. &Keyword { "liste", TokenKindOpenList, StringValue("[") },
  33. &Keyword { "fini", TokenKindCloseList, StringValue("]") },
  34. &Keyword { "le", TokenKindGet, StringValue("$") },
  35. &Keyword { "la", TokenKindGet, StringValue("$") },
  36. }
  37. var _ Value = &Keyword{}
  38. const KeywordType = TypeValue("Keyword")
  39. func (kw * Keyword) String() string {
  40. return fmt.Sprintf("Keyword: %s %v %v", kw.Name, kw.TokenKind, kw.Value)
  41. }
  42. func (*Keyword) Type() TypeValue {
  43. return KeywordType
  44. }
  45. func (from * Keyword) Convert(to interface{}) error {
  46. switch toPtr := to.(type) {
  47. case **Keyword:
  48. (*toPtr) = from
  49. case *Keyword:
  50. (*toPtr) = *from
  51. case *Value:
  52. (*toPtr) = from
  53. default:
  54. return NewErrorValuef("Cannot convert Keyword value %v to %v", from, to)
  55. }
  56. return nil
  57. }
  58. func (vm * VM) AddKeyword(kw *Keyword) *Keyword {
  59. found := vm.Lookup(KeywordName)
  60. list, ok := found.(*ListValue)
  61. if !ok || list == nil {
  62. list = NewListValue()
  63. vm.Register(KeywordName, list)
  64. }
  65. list.Append(kw)
  66. return kw
  67. }
  68. func keyword(vm *VM, val ...Value) []Value {
  69. var name string = val[0].String()
  70. var tokenName string = val[1].String()
  71. var value = val[2]
  72. tokenkind, ok := NamesTokenKind[tokenName]
  73. if ! ok {
  74. return Fail(NewErrorValuef("Token kind unknown: %s", tokenName))
  75. }
  76. kw := &Keyword{ Name: name, TokenKind: tokenkind, Value: value }
  77. return Ok(vm.AddKeyword(kw))
  78. }
  79. func keywords(vm *VM, val ...Value) []Value {
  80. kws := []Value{}
  81. for i := 2 ; i < len(val) ; i += 3 {
  82. var name string = val[i-2].String()
  83. var tokenName string = val[i-1].String()
  84. var value = val[i]
  85. tokenkind, ok := NamesTokenKind[tokenName]
  86. if !ok {
  87. return Fail(NewErrorValuef("Token kind unknown: %s", tokenName))
  88. }
  89. kw := &Keyword{ Name: name, TokenKind: tokenkind, Value: value }
  90. kws = append(kws, kw)
  91. }
  92. listValue := NewListValue(kws...)
  93. vm.RegisterTop(KeywordName, listValue)
  94. return Ok(listValue)
  95. }
  96. const KeywordName = "__muesli_keywords__"
  97. func (vm * VM) StoreKeywords(keywords []*Keyword) *ListValue {
  98. vm.Register("Keyword", KeywordType)
  99. vm.RegisterBuiltin("keyword", keyword).Takes(StringType, StringType, AnyType).Returns(KeywordType)
  100. vm.RegisterBuiltin("keywords", keyword).Takes(StringType, StringType, AnyType).Returns(ListType)
  101. list := NewValueArray()
  102. for _, kw := range keywords {
  103. list = append(list, kw)
  104. }
  105. listValue := NewListValue(list...)
  106. vm.RegisterTop(KeywordName, listValue)
  107. return listValue
  108. }
  109. func (vm * VM) LoadKeywords() ([]*Keyword) {
  110. found := vm.Lookup(KeywordName)
  111. list, ok := found.(*ListValue)
  112. if !ok || list == nil {
  113. return nil
  114. }
  115. result := []*Keyword{}
  116. for _, kw := range list.List {
  117. result = append(result, kw.(*Keyword))
  118. }
  119. return result
  120. }