mt-lang 0.3.14 → 0.3.17

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (87) hide show
  1. checksums.yaml +4 -4
  2. data/README.md +2 -2
  3. data/docs/index.html +8 -8
  4. data/docs/language-design.md +7 -12
  5. data/docs/language-manual.md +20 -8
  6. data/lib/milk_tea/base.rb +1 -1
  7. data/lib/milk_tea/core/ast.rb +2 -2
  8. data/lib/milk_tea/core/{binding_types.rb → bindings.rb} +1 -1
  9. data/lib/milk_tea/core/c_backend.rb +14 -15
  10. data/lib/milk_tea/core/compile_time.rb +181 -2
  11. data/lib/milk_tea/core/control_flow/builder.rb +62 -2
  12. data/lib/milk_tea/core/control_flow/constant_propagation.rb +1 -1
  13. data/lib/milk_tea/core/{compatibility_helpers.rb → intrinsics.rb} +2 -2
  14. data/lib/milk_tea/core/lexer.rb +10 -14
  15. data/lib/milk_tea/core/lowering/async/analysis.rb +3 -9
  16. data/lib/milk_tea/core/lowering/async/lowering.rb +2 -10
  17. data/lib/milk_tea/core/lowering/async/normalization.rb +2 -7
  18. data/lib/milk_tea/core/lowering/block.rb +1 -5
  19. data/lib/milk_tea/core/lowering/proc.rb +1 -5
  20. data/lib/milk_tea/core/lowering/scans.rb +3 -1
  21. data/lib/milk_tea/core/lowering/utils.rb +1 -27
  22. data/lib/milk_tea/core/lowering.rb +18 -18
  23. data/lib/milk_tea/core/module_loader.rb +26 -15
  24. data/lib/milk_tea/core/parser/statements.rb +18 -12
  25. data/lib/milk_tea/core/parser.rb +17 -17
  26. data/lib/milk_tea/core/pretty_printer/ast_formatter.rb +3 -11
  27. data/lib/milk_tea/core/semantic_analyzer/analysis_context.rb +2 -3
  28. data/lib/milk_tea/core/semantic_analyzer/flow_refinement.rb +1 -1
  29. data/lib/milk_tea/core/semantic_analyzer/function_binding.rb +1 -2
  30. data/lib/milk_tea/core/semantic_analyzer/nullability.rb +2 -4
  31. data/lib/milk_tea/core/semantic_analyzer/statements.rb +2 -8
  32. data/lib/milk_tea/core/semantic_analyzer.rb +1 -1
  33. data/lib/milk_tea/core.rb +6 -2
  34. data/lib/milk_tea/dap/lldb_dap_backend.rb +153 -0
  35. data/lib/milk_tea/dap/server/lldb_backend.rb +1 -1
  36. data/lib/milk_tea/dap.rb +1 -1
  37. data/lib/milk_tea/lsp.rb +1 -7
  38. data/lib/milk_tea/{bindings/cli.rb → tooling/bindgen_cli.rb} +1 -1
  39. data/lib/milk_tea/tooling/linter/imports_platform.rb +2 -4
  40. data/lib/milk_tea/tooling/linter/release_rules.rb +1 -6
  41. data/lib/milk_tea/tooling/linter/source_helpers.rb +0 -6
  42. data/lib/milk_tea/tooling/linter/visitors.rb +4 -8
  43. data/lib/milk_tea/tooling/sexpr_dumper.rb +2 -0
  44. data/lib/milk_tea/tooling.rb +1 -1
  45. data/std/asset_pack.mt +1 -1
  46. data/std/async/libuv_runtime.mt +6 -6
  47. data/std/async/mailbox.mt +4 -4
  48. data/std/cookie.mt +2 -2
  49. data/std/crypto.mt +1 -1
  50. data/std/curl/runtime.mt +10 -10
  51. data/std/fs.linux.mt +26 -26
  52. data/std/fs.windows.mt +22 -22
  53. data/std/goap.mt +2 -2
  54. data/std/http/server.mt +21 -21
  55. data/std/http.mt +14 -14
  56. data/std/jobs.mt +4 -4
  57. data/std/json.mt +5 -5
  58. data/std/log.mt +1 -1
  59. data/std/mem/tracking.mt +1 -1
  60. data/std/net/channel.mt +4 -4
  61. data/std/net/clock.mt +6 -6
  62. data/std/net/discovery.mt +7 -7
  63. data/std/net/lobby.mt +10 -10
  64. data/std/net/manager.mt +1 -1
  65. data/std/net/mux.mt +4 -4
  66. data/std/net/nat.mt +4 -4
  67. data/std/net/packet.mt +3 -3
  68. data/std/net/punch.mt +3 -3
  69. data/std/net/rpc.mt +3 -3
  70. data/std/net/session.mt +15 -15
  71. data/std/net/stun.mt +4 -4
  72. data/std/net/turn.mt +4 -4
  73. data/std/oauth2.mt +12 -12
  74. data/std/path.mt +8 -8
  75. data/std/process.mt +4 -4
  76. data/std/raylib/packed_assets.mt +5 -5
  77. data/std/serialize.mt +1 -1
  78. data/std/tar.mt +10 -10
  79. data/std/terminal.mt +18 -18
  80. data/std/tls.mt +8 -8
  81. data/std/uri.mt +1 -1
  82. data/std/utility.mt +1 -1
  83. metadata +7 -9
  84. data/lib/milk_tea/core/compile_time/const_eval.rb +0 -182
  85. data/lib/milk_tea/core/module_loader/errors.rb +0 -23
  86. data/lib/milk_tea/dap/backends/lldb_dap.rb +0 -156
  87. /data/lib/milk_tea/core/lowering/{async.rb → async/frame_builder.rb} +0 -0
@@ -1,182 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- require_relative "../types/layout"
4
-
5
- module MilkTea
6
- module ConstEval
7
-
8
- def self.evaluate(expression, resolve_identifier:, resolve_member_access:, resolve_type_ref: nil, resolve_call: nil)
9
- Evaluator.new(
10
- resolve_identifier:,
11
- resolve_member_access:,
12
- resolve_type_ref:,
13
- resolve_call:,
14
- ).evaluate(expression)
15
- end
16
-
17
- def self.equality_result(left, right)
18
- return left == right if left.is_a?(Numeric) && right.is_a?(Numeric)
19
- return left == right if left.is_a?(String) && right.is_a?(String)
20
- return left == right if boolean_value?(left) && boolean_value?(right)
21
- return left == right if left.is_a?(Types::Base) && right.is_a?(Types::Base)
22
-
23
- nil
24
- end
25
-
26
- def self.boolean_value?(value)
27
- value == true || value == false
28
- end
29
-
30
- class Evaluator
31
- def initialize(resolve_identifier:, resolve_member_access:, resolve_type_ref: nil, resolve_call: nil)
32
- @resolve_identifier = resolve_identifier
33
- @resolve_member_access = resolve_member_access
34
- @resolve_type_ref = resolve_type_ref
35
- @resolve_call = resolve_call
36
- end
37
-
38
- def evaluate(expression)
39
- case expression
40
- when AST::ErrorExpr
41
- nil
42
- when AST::ExpressionList
43
- expression.elements.filter_map { |element| evaluate(element) }
44
- when AST::IntegerLiteral, AST::FloatLiteral, AST::BooleanLiteral
45
- expression.value
46
- when AST::StringLiteral
47
- expression.value
48
- when AST::Identifier
49
- @resolve_identifier&.call(expression)
50
- when AST::MemberAccess
51
- @resolve_member_access&.call(expression)
52
- when AST::Call
53
- @resolve_call&.call(expression)
54
- when AST::Specialization
55
- @resolve_call&.call(expression)
56
- when AST::SizeofExpr
57
- type = resolve_layout_type(expression.type)
58
- type && Layout.size_of(type)
59
- when AST::AlignofExpr
60
- type = resolve_layout_type(expression.type)
61
- type && Layout.alignment_of(type)
62
- when AST::OffsetofExpr
63
- type = resolve_layout_type(expression.type)
64
- if type
65
- result = Layout.offset_of(type, expression.field)
66
- return result if result
67
-
68
- id_expr = AST::Identifier.new(name: expression.field)
69
- value = @resolve_identifier&.call(id_expr)
70
- if value.is_a?(Types::FieldHandle)
71
- return Layout.offset_of(type, value.field_name)
72
- end
73
- end
74
- nil
75
- when AST::UnaryOp
76
- evaluate_unary(expression)
77
- when AST::BinaryOp
78
- evaluate_binary(expression)
79
- when AST::IfExpr
80
- condition = evaluate(expression.condition)
81
- return unless ConstEval.boolean_value?(condition)
82
-
83
- evaluate(condition ? expression.then_expression : expression.else_expression)
84
- else
85
- nil
86
- end
87
- end
88
-
89
- def resolve_layout_type(type_ref)
90
- return unless @resolve_type_ref
91
-
92
- @resolve_type_ref.call(type_ref)
93
- end
94
-
95
- def evaluate_unary(expression)
96
- operand = evaluate(expression.operand)
97
-
98
- case expression.operator
99
- when "+"
100
- operand.is_a?(Numeric) ? operand : nil
101
- when "-"
102
- operand.is_a?(Numeric) ? -operand : nil
103
- when "~"
104
- operand.is_a?(Integer) ? ~operand : nil
105
- when "not"
106
- ConstEval.boolean_value?(operand) ? !operand : nil
107
- end
108
- end
109
-
110
- def evaluate_binary(expression)
111
- left = evaluate(expression.left)
112
-
113
- case expression.operator
114
- when "and"
115
- return unless ConstEval.boolean_value?(left)
116
- return false if left == false
117
-
118
- right = evaluate(expression.right)
119
- return right if ConstEval.boolean_value?(right)
120
-
121
- return nil
122
- when "or"
123
- return unless ConstEval.boolean_value?(left)
124
- return true if left == true
125
-
126
- right = evaluate(expression.right)
127
- return right if ConstEval.boolean_value?(right)
128
-
129
- return nil
130
- end
131
-
132
- right = evaluate(expression.right)
133
-
134
- case expression.operator
135
- when "=="
136
- ConstEval.equality_result(left, right)
137
- when "!="
138
- result = ConstEval.equality_result(left, right)
139
- result.nil? ? nil : !result
140
- when "+"
141
- left.is_a?(Numeric) && right.is_a?(Numeric) ? left + right : nil
142
- when "-"
143
- left.is_a?(Numeric) && right.is_a?(Numeric) ? left - right : nil
144
- when "*"
145
- left.is_a?(Numeric) && right.is_a?(Numeric) ? left * right : nil
146
- when "/"
147
- return unless left.is_a?(Numeric) && right.is_a?(Numeric)
148
- raise CompileTime::Error, "division by zero" if zero_numeric?(right)
149
-
150
- left / right
151
- when "%"
152
- return unless left.is_a?(Integer) && right.is_a?(Integer)
153
- raise CompileTime::Error, "modulo by zero" if right.zero?
154
-
155
- left % right
156
- when "<<"
157
- left.is_a?(Integer) && right.is_a?(Integer) ? left << right : nil
158
- when ">>"
159
- left.is_a?(Integer) && right.is_a?(Integer) ? left >> right : nil
160
- when "&"
161
- left.is_a?(Integer) && right.is_a?(Integer) ? left & right : nil
162
- when "|"
163
- left.is_a?(Integer) && right.is_a?(Integer) ? left | right : nil
164
- when "^"
165
- left.is_a?(Integer) && right.is_a?(Integer) ? left ^ right : nil
166
- when "<"
167
- left.is_a?(Numeric) && right.is_a?(Numeric) ? left < right : nil
168
- when "<="
169
- left.is_a?(Numeric) && right.is_a?(Numeric) ? left <= right : nil
170
- when ">"
171
- left.is_a?(Numeric) && right.is_a?(Numeric) ? left > right : nil
172
- when ">="
173
- left.is_a?(Numeric) && right.is_a?(Numeric) ? left >= right : nil
174
- end
175
- end
176
-
177
- def zero_numeric?(value)
178
- (value.is_a?(Integer) && value.zero?) || (value.is_a?(Float) && value.zero?)
179
- end
180
- end
181
- end
182
- end
@@ -1,23 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- module MilkTea
4
- class ModuleLoadError < StandardError
5
- attr_reader :path, :line, :column
6
-
7
- def initialize(message, path:, line: nil, column: nil)
8
- @path = path
9
- @line = line
10
- @column = column
11
- super("#{message}: #{path}")
12
- end
13
-
14
- def code
15
- "module/error"
16
- end
17
- end
18
-
19
- class ModuleLoader
20
- ImportResolution = Data.define(:modules, :errors)
21
- ImportResolutionError = Data.define(:import, :error)
22
- end
23
- end
@@ -1,156 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- require "open3"
4
- require "thread"
5
- require "timeout"
6
-
7
- module MilkTea
8
- module DAP
9
- module Backends
10
- # Thin bridge to an lldb-dap compatible adapter process.
11
- class LLDBDAP
12
- def initialize(adapter_command: ["lldb-dap"], on_event: nil, on_request: nil)
13
- @adapter_command = adapter_command
14
- @on_event = on_event
15
- @on_request = on_request
16
- @protocol = nil
17
- @stdin = nil
18
- @stdout = nil
19
- @stderr = nil
20
- @wait_thread = nil
21
- @reader_thread = nil
22
- @stderr_thread = nil
23
- @write_mutex = Mutex.new
24
- @pending_mutex = Mutex.new
25
- @pending = {}
26
- @next_seq = 1
27
- end
28
-
29
- def start!
30
- return if running?
31
-
32
- @stdin, @stdout, @stderr, @wait_thread = Open3.popen3(*@adapter_command)
33
- @protocol = Protocol.new(input: @stdout, output: @stdin)
34
-
35
- @reader_thread = Thread.new { read_loop }
36
- @stderr_thread = Thread.new { drain_stderr }
37
- end
38
-
39
- def running?
40
- !@wait_thread.nil? && @wait_thread.alive?
41
- end
42
-
43
- def request(command, arguments = {}, timeout: 5)
44
- start! unless running?
45
-
46
- seq = next_seq
47
- queue = Queue.new
48
- @pending_mutex.synchronize do
49
- @pending[seq] = queue
50
- end
51
-
52
- @write_mutex.synchronize do
53
- @protocol.write_message({
54
- seq: seq,
55
- type: "request",
56
- command: command,
57
- arguments: arguments
58
- })
59
- end
60
-
61
- Timeout.timeout(timeout) { queue.pop }
62
- rescue Timeout::Error
63
- {
64
- "type" => "response",
65
- "request_seq" => seq,
66
- "success" => false,
67
- "message" => "backend request timed out: #{command}"
68
- }
69
- ensure
70
- @pending_mutex.synchronize { @pending.delete(seq) }
71
- end
72
-
73
- def stop!
74
- @stdin&.close
75
- @stdout&.close
76
- @stderr&.close
77
- if @wait_thread&.alive?
78
- Process.kill("TERM", @wait_thread.pid)
79
- end
80
- rescue StandardError
81
- nil
82
- ensure
83
- @wait_thread&.join(0.2)
84
- @reader_thread&.join(0.2)
85
- @stderr_thread&.join(0.2)
86
- @stdin = nil
87
- @stdout = nil
88
- @stderr = nil
89
- @wait_thread = nil
90
- @reader_thread = nil
91
- @stderr_thread = nil
92
- end
93
-
94
- def next_seq
95
- seq = @next_seq
96
- @next_seq += 1
97
- seq
98
- end
99
-
100
- def read_loop
101
- loop do
102
- message = @protocol.read_message
103
- break if message.nil?
104
-
105
- if message["type"] == "response"
106
- queue = @pending_mutex.synchronize { @pending[message["request_seq"]] }
107
- queue&.push(message)
108
- elsif message["type"] == "event"
109
- @on_event&.call(message)
110
- elsif message["type"] == "request"
111
- handle_adapter_request(message)
112
- end
113
- end
114
- rescue StandardError
115
- nil
116
- ensure
117
- @pending_mutex.synchronize do
118
- @pending.each_value do |queue|
119
- queue.push({
120
- "type" => "response",
121
- "success" => false,
122
- "message" => "backend closed"
123
- })
124
- end
125
- @pending.clear
126
- end
127
- end
128
-
129
- def drain_stderr
130
- return unless @stderr
131
-
132
- @stderr.each_line do |_line|
133
- # Intentionally ignored in this bridge layer.
134
- end
135
- rescue StandardError
136
- nil
137
- end
138
-
139
- def handle_adapter_request(message)
140
- response = @on_request&.call(message)
141
- response ||= {
142
- "type" => "response",
143
- "request_seq" => message["seq"],
144
- "success" => false,
145
- "command" => message["command"],
146
- "message" => "unsupported reverse request: #{message['command']}"
147
- }
148
-
149
- @write_mutex.synchronize do
150
- @protocol.write_message(response)
151
- end
152
- end
153
- end
154
- end
155
- end
156
- end