function.odin 3.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147
  1. package text_template
  2. import "core:fmt"
  3. import "core:reflect"
  4. import "core:strconv"
  5. Function :: #type proc(args: []any) -> (value: any, err: Error)
  6. @(private)
  7. new_any :: proc(x: $T) -> any {
  8. ptr := new_clone(x)
  9. return any{ptr, typeid_of(T)}
  10. }
  11. builtin_funcs: map[string]Function
  12. @(private, init)
  13. init_builtin_funcs :: proc() {
  14. builtin_funcs["and"] = nil // requires shortcircuiting behaviour so implemented internally
  15. builtin_funcs["or"] = nil // requires shortcircuiting behaviour so implemented internally
  16. builtin_funcs["not"] = proc(args: []any) -> (value: any, err: Error) {
  17. if len(args) != 1 {
  18. err = .Invalid_Argument_Count
  19. return
  20. }
  21. t, _ := is_true(args[0])
  22. return new_any(t), nil
  23. }
  24. builtin_funcs["index"] = proc(args: []any) -> (value: any, err: Error) {
  25. if len(args) < 2 {
  26. err = .Invalid_Argument_Count
  27. return
  28. }
  29. arg := args[0]
  30. for idx in args[1:] {
  31. i, ok := reflect.as_int(idx)
  32. if !ok {
  33. err = .Invalid_Argument_Type
  34. return
  35. }
  36. if reflect.length(arg) < i {
  37. return nil, .Out_Of_Bounds_Access
  38. }
  39. arg = reflect.index(arg, i)
  40. }
  41. return arg, nil
  42. }
  43. builtin_funcs["len"] = proc(args: []any) -> (value: any, err: Error) {
  44. if len(args) != 1 {
  45. err = .Invalid_Argument_Count
  46. return
  47. }
  48. n := reflect.length(args[0])
  49. return new_any(n), nil
  50. }
  51. builtin_funcs["int"] = proc(args: []any) -> (value: any, err: Error) {
  52. if len(args) != 1 {
  53. err = .Invalid_Argument_Count
  54. return
  55. }
  56. res: i64
  57. switch v in get_value(args[0]) {
  58. case bool:
  59. res = i64(v)
  60. case i64:
  61. res = i64(v)
  62. case f64:
  63. res = i64(v)
  64. case string:
  65. if value, ok := strconv.parse_f64(v); ok {
  66. res = i64(value)
  67. } else if value, ok := strconv.parse_i64(v); ok {
  68. res = i64(value)
  69. } else {
  70. return nil, .Invalid_Argument_Type
  71. }
  72. case:
  73. return nil, .Invalid_Argument_Type
  74. }
  75. return new_any(res), nil
  76. }
  77. builtin_funcs["float"] = proc(args: []any) -> (value: any, err: Error) {
  78. if len(args) != 1 {
  79. err = .Invalid_Argument_Count
  80. return
  81. }
  82. res: f64
  83. switch v in get_value(args[0]) {
  84. case bool:
  85. res = f64(i64(v))
  86. case i64:
  87. res = f64(v)
  88. case f64:
  89. res = f64(v)
  90. case string:
  91. if value, ok := strconv.parse_f64(v); ok {
  92. res = f64(value)
  93. } else if value, ok := strconv.parse_i64(v); ok {
  94. res = f64(value)
  95. } else {
  96. return nil, .Invalid_Argument_Type
  97. }
  98. case:
  99. return nil, .Invalid_Argument_Type
  100. }
  101. return new_any(res), nil
  102. }
  103. builtin_funcs["print"] = proc(args: []any) -> (value: any, err: Error) {
  104. return new_any(fmt.aprint(..args)), nil
  105. }
  106. builtin_funcs["println"] = proc(args: []any) -> (value: any, err: Error) {
  107. return new_any(fmt.aprintln(..args)), nil
  108. }
  109. builtin_funcs["printf"] = proc(args: []any) -> (value: any, err: Error) {
  110. if len(args) < 1 {
  111. err = .Invalid_Argument_Count
  112. return
  113. }
  114. format_any := args[0]
  115. format_any.id = reflect.typeid_base(format_any.id)
  116. format: string
  117. switch v in format_any {
  118. case string:
  119. format = v
  120. case cstring:
  121. format = string(v)
  122. case:
  123. err = .Invalid_Argument_Type
  124. return
  125. }
  126. other_args := args[1:]
  127. return new_any(fmt.aprintf(format, ..other_args)), nil
  128. }
  129. }