string.go 1.5 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970
  1. package checker
  2. import (
  3. "kumachan/transformer/node"
  4. "strings"
  5. )
  6. func (impl StringLiteral) ExprVal() {}
  7. type StringLiteral struct {
  8. Value [] rune
  9. }
  10. func (impl StringFormatter) ExprVal() {}
  11. type StringFormatter struct {
  12. Segments [] []rune
  13. Arity uint
  14. }
  15. func CheckString(s node.StringLiteral, ctx ExprContext) (SemiExpr, *ExprError) {
  16. var info = ctx.GetExprInfo(s.Node)
  17. return LiftTyped(Expr {
  18. Type: NamedType {
  19. Name: __String,
  20. Args: make([]Type, 0),
  21. },
  22. Info: info,
  23. Value: StringLiteral { s.Value },
  24. }), nil
  25. }
  26. func CheckText(text node.Text, ctx ExprContext) (SemiExpr, *ExprError) {
  27. var info = ctx.GetExprInfo(text.Node)
  28. var template = text.Template
  29. var segments = make([] []rune, 0)
  30. var arity uint = 0
  31. var buf strings.Builder
  32. for _, char := range template {
  33. if char == TextPlaceholder {
  34. var seg = buf.String()
  35. buf.Reset()
  36. segments = append(segments, []rune(seg))
  37. arity += 1
  38. } else {
  39. buf.WriteRune(char)
  40. }
  41. }
  42. var last = buf.String()
  43. if last != "" {
  44. segments = append(segments, []rune(last))
  45. }
  46. var elements = make([]Type, arity)
  47. for i := uint(0); i < arity; i += 1 {
  48. elements[i] = NamedType { Name: __String, Args: make([]Type, 0) }
  49. }
  50. var t Type = AnonymousType { Func {
  51. Input: AnonymousType { Tuple { elements } },
  52. Output: NamedType { Name: __String, Args: make([]Type, 0) },
  53. } }
  54. return LiftTyped(Expr {
  55. Type: t,
  56. Value: StringFormatter {
  57. Segments: segments,
  58. Arity: arity,
  59. },
  60. Info: info,
  61. }), nil
  62. }