mt-lang 0.3.5 → 0.3.6
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.
- checksums.yaml +4 -4
- data/lib/milk_tea/base.rb +1 -1
- data/lib/milk_tea/core/c_backend/expressions.rb +6 -1
- data/lib/milk_tea/core/c_backend/statements.rb +4 -0
- data/lib/milk_tea/core/c_backend.rb +8 -0
- data/lib/milk_tea/core/compile_time.rb +19 -1
- data/lib/milk_tea/core/ir.rb +3 -1
- data/lib/milk_tea/core/lowering/block.rb +4 -3
- data/lib/milk_tea/core/lowering/declarations.rb +2 -1
- data/lib/milk_tea/core/lowering/resolve.rb +3 -3
- data/lib/milk_tea/core/semantic_analyzer/top_level.rb +23 -0
- data/lib/milk_tea/tooling/error_formatter.rb +18 -14
- data/std/mem/ptr.mt +9 -0
- metadata +2 -2
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: 2d5caebfa149a9d43d576f3cbf1b36b175ce70b28bfe474bc942fc2d11f0f1e8
|
|
4
|
+
data.tar.gz: bf9f4a30b1cabadbed2b2d276dd29d567e118d008000791eefb2ec0e81f80c4f
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: 681c1614c3449f16bb71fbb0f9ee7e9ec10420e302602b131c4ed813b087742e7474ff71e9111f5d35cb1e4315eb440c3c85e29d66e8c733159063cbe946ea01
|
|
7
|
+
data.tar.gz: 6ea9caabdb7407f64d634f6576135df74e614878f81680777062c2e5f64f75278bb56f71bb48406153e40745e2d2b458e99c46193c9c85837c2b28b3b7aca4b4
|
data/lib/milk_tea/base.rb
CHANGED
|
@@ -33,7 +33,12 @@ module MilkTea
|
|
|
33
33
|
when IR::NullableSpanIndex
|
|
34
34
|
"#{nullable_span_index_helper_name(expression.receiver_type)}(#{emit_expression(expression.receiver)}, #{emit_expression(expression.index)})"
|
|
35
35
|
when IR::Call
|
|
36
|
-
|
|
36
|
+
if array_type?(expression.type)
|
|
37
|
+
location = [@source_path, @current_line && "line #{@current_line}"].compact.join(" ")
|
|
38
|
+
msg = "array-return call must be materialized before C emission"
|
|
39
|
+
msg += " (#{location})" unless location.empty?
|
|
40
|
+
raise CBackendError.new(msg, line: @current_line, path: @source_path)
|
|
41
|
+
end
|
|
37
42
|
|
|
38
43
|
emit_call_expression(expression)
|
|
39
44
|
when IR::Unary
|
|
@@ -23,6 +23,10 @@ module MilkTea
|
|
|
23
23
|
indent = INDENT * level
|
|
24
24
|
aliases = checked_index_aliases_for_statement(statement)
|
|
25
25
|
alias_lines = emit_checked_index_alias_declarations(aliases, indent)
|
|
26
|
+
if statement.respond_to?(:line) && statement.line
|
|
27
|
+
@current_line = statement.line
|
|
28
|
+
@source_path ||= statement.source_path if statement.respond_to?(:source_path) && statement.source_path
|
|
29
|
+
end
|
|
26
30
|
line_directive = if @emit_line_directives && statement.respond_to?(:line) && statement.line
|
|
27
31
|
sp = (statement.respond_to?(:source_path) && statement.source_path) || @source_path
|
|
28
32
|
sp ? ["#line #{statement.line} #{sp.inspect}"] : []
|
|
@@ -55,6 +55,8 @@ module MilkTea
|
|
|
55
55
|
@checked_index_alias_id = 0
|
|
56
56
|
@loop_guard_id = 0
|
|
57
57
|
@emitted_span_type_names = Set.new
|
|
58
|
+
@source_path = program.source_path
|
|
59
|
+
@current_line = nil
|
|
58
60
|
end
|
|
59
61
|
|
|
60
62
|
def emit
|
|
@@ -218,10 +220,16 @@ module MilkTea
|
|
|
218
220
|
end
|
|
219
221
|
|
|
220
222
|
constants.each do |constant|
|
|
223
|
+
@current_line = constant.line if constant.line
|
|
224
|
+
@source_path ||= constant.source_path if constant.source_path
|
|
221
225
|
lines << "#{constant_storage(constant.type)} #{c_declaration(constant.type, constant.linkage_name)} = #{emit_initializer(constant.value)};"
|
|
222
226
|
end
|
|
223
227
|
@program.globals.each do |global|
|
|
224
228
|
next unless emitted_globals.include?(global)
|
|
229
|
+
if global.respond_to?(:line) && global.line
|
|
230
|
+
@current_line = global.line
|
|
231
|
+
@source_path ||= global.source_path if global.respond_to?(:source_path) && global.source_path
|
|
232
|
+
end
|
|
225
233
|
lines << "#{global_storage(global.type)} #{c_declaration(global.type, global.linkage_name)} = #{emit_initializer(global.value)};"
|
|
226
234
|
end
|
|
227
235
|
lines << "" unless constants.empty? && @program.globals.empty?
|
|
@@ -114,7 +114,12 @@ module MilkTea
|
|
|
114
114
|
else
|
|
115
115
|
@checker.instance_variable_get(:@ctx).types
|
|
116
116
|
end
|
|
117
|
-
|
|
117
|
+
callee_name = if call_expr.callee.is_a?(AST::Specialization) && call_expr.callee.callee.respond_to?(:name)
|
|
118
|
+
call_expr.callee.callee.name
|
|
119
|
+
elsif call_expr.callee.respond_to?(:name)
|
|
120
|
+
call_expr.callee.name
|
|
121
|
+
end
|
|
122
|
+
if callee_name && (type = types[callee_name]) && type.is_a?(Types::Struct)
|
|
118
123
|
fields = {}
|
|
119
124
|
call_expr.arguments.each do |argument|
|
|
120
125
|
val = evaluate_expression(argument.value, scopes:)
|
|
@@ -123,6 +128,19 @@ module MilkTea
|
|
|
123
128
|
end
|
|
124
129
|
next fields
|
|
125
130
|
end
|
|
131
|
+
|
|
132
|
+
if call_expr.callee.is_a?(AST::Specialization) && @checker.respond_to?(:resolve_type_expression)
|
|
133
|
+
resolved = @checker.send(:resolve_type_expression, call_expr.callee)
|
|
134
|
+
if resolved && @checker.respond_to?(:array_type?) && @checker.send(:array_type?, resolved)
|
|
135
|
+
values = []
|
|
136
|
+
call_expr.arguments.each do |argument|
|
|
137
|
+
val = evaluate_expression(argument.value, scopes:)
|
|
138
|
+
return nil unless val
|
|
139
|
+
values << val
|
|
140
|
+
end
|
|
141
|
+
next values
|
|
142
|
+
end
|
|
143
|
+
end
|
|
126
144
|
|
|
127
145
|
@checker.send(:evaluate_compile_time_const_value, call_expr, scopes:)
|
|
128
146
|
},
|
data/lib/milk_tea/core/ir.rb
CHANGED
|
@@ -6,7 +6,9 @@ module MilkTea
|
|
|
6
6
|
def initialize(module_name:, includes:, constants:, globals:, opaques:, structs:, unions:, enums:, variants:, static_asserts:, functions:, source_path: nil) = super
|
|
7
7
|
end
|
|
8
8
|
Include = Data.define(:header)
|
|
9
|
-
Constant = Data.define(:name, :linkage_name, :type, :value)
|
|
9
|
+
Constant = Data.define(:name, :linkage_name, :type, :value, :line, :source_path) do
|
|
10
|
+
def initialize(name:, linkage_name:, type:, value:, line: nil, source_path: nil) = super
|
|
11
|
+
end
|
|
10
12
|
Global = Data.define(:name, :linkage_name, :type, :value)
|
|
11
13
|
OpaqueDecl = Data.define(:name, :linkage_name, :forward_declarable, :source_module) do
|
|
12
14
|
def initialize(name:, linkage_name:, forward_declarable:, source_module: nil) = super
|
|
@@ -353,7 +353,8 @@ module MilkTea
|
|
|
353
353
|
value = lower_static_storage_initializer(decl.value, env:, expected_type: decl.type ? resolve_type_ref(decl.type) : nil)
|
|
354
354
|
type = decl.type ? resolve_type_ref(decl.type) : infer_expression_type(decl.value, env:)
|
|
355
355
|
linkage_name = value_c_name(decl.name)
|
|
356
|
-
constant = IR::Constant.new(name: decl.name, linkage_name:, type:, value
|
|
356
|
+
constant = IR::Constant.new(name: decl.name, linkage_name:, type:, value:,
|
|
357
|
+
line: decl.line, source_path: @ctx.current_analysis_path)
|
|
357
358
|
@artifacts.emitted_declarations << constant
|
|
358
359
|
[]
|
|
359
360
|
end
|
|
@@ -511,7 +512,7 @@ module MilkTea
|
|
|
511
512
|
env: local_env,
|
|
512
513
|
expected_type: target.type,
|
|
513
514
|
allow_root_statement_foreign: true,
|
|
514
|
-
materialize_array_calls:
|
|
515
|
+
materialize_array_calls: true,
|
|
515
516
|
)
|
|
516
517
|
lowered.concat(prepared_setup)
|
|
517
518
|
if (foreign_call = foreign_call_info(prepared_value, local_env))
|
|
@@ -700,7 +701,7 @@ module MilkTea
|
|
|
700
701
|
env: local_env,
|
|
701
702
|
expected_type: storage_type,
|
|
702
703
|
allow_root_statement_foreign: true,
|
|
703
|
-
materialize_array_calls:
|
|
704
|
+
materialize_array_calls: true,
|
|
704
705
|
)
|
|
705
706
|
lowered.concat(prepared_setup)
|
|
706
707
|
end
|
|
@@ -41,7 +41,8 @@ module MilkTea
|
|
|
41
41
|
value = lower_static_storage_initializer(decl.value, env: empty_env, expected_type: type)
|
|
42
42
|
end
|
|
43
43
|
|
|
44
|
-
IR::Constant.new(name: decl.name, linkage_name: value_c_name(decl.name), type:, value
|
|
44
|
+
IR::Constant.new(name: decl.name, linkage_name: value_c_name(decl.name), type:, value:,
|
|
45
|
+
line: decl.line, source_path: @ctx.current_analysis_path)
|
|
45
46
|
end
|
|
46
47
|
end
|
|
47
48
|
|
|
@@ -666,11 +666,11 @@ module MilkTea
|
|
|
666
666
|
end
|
|
667
667
|
|
|
668
668
|
if (callable_resolution = resolve_specialized_callable_binding(callee, env:))
|
|
669
|
-
callable_kind, function_binding, receiver = callable_resolution
|
|
669
|
+
callable_kind, function_binding, receiver, method_entry_receiver_type = callable_resolution
|
|
670
670
|
if callable_kind == :method
|
|
671
671
|
return [
|
|
672
672
|
:method,
|
|
673
|
-
function_binding_c_name(function_binding, module_name: function_binding.owner.module_name, receiver_type:
|
|
673
|
+
function_binding_c_name(function_binding, module_name: function_binding.owner.module_name, receiver_type: method_entry_receiver_type),
|
|
674
674
|
receiver,
|
|
675
675
|
function_binding.type,
|
|
676
676
|
function_binding,
|
|
@@ -1277,7 +1277,7 @@ module MilkTea
|
|
|
1277
1277
|
return nil unless binding
|
|
1278
1278
|
|
|
1279
1279
|
type_arguments = resolve_specialization_type_arguments(expression)
|
|
1280
|
-
[callable_kind, instantiate_function_binding_with_receiver(binding, type_arguments, receiver_type:), receiver]
|
|
1280
|
+
[callable_kind, instantiate_function_binding_with_receiver(binding, type_arguments, receiver_type:), receiver, method_entry_receiver_type]
|
|
1281
1281
|
end
|
|
1282
1282
|
|
|
1283
1283
|
def resolve_default_specialization(expression, env:)
|
|
@@ -376,6 +376,29 @@ module MilkTea
|
|
|
376
376
|
else
|
|
377
377
|
callee_name = expression.callee.callee.is_a?(AST::Identifier) ? expression.callee.callee.name : nil
|
|
378
378
|
if callee_name
|
|
379
|
+
resolved_type = resolve_type_expression(expression.callee)
|
|
380
|
+
if resolved_type && resolved_type.is_a?(Types::Struct)
|
|
381
|
+
fields = {}
|
|
382
|
+
expression.arguments.each do |argument|
|
|
383
|
+
val = CompileTime.evaluate(argument.value, resolve_identifier: lambda { |id|
|
|
384
|
+
if scopes
|
|
385
|
+
binding = lookup_value(id.name, scopes)
|
|
386
|
+
return binding.const_value unless binding&.const_value.nil?
|
|
387
|
+
end
|
|
388
|
+
resolve_current_module_const_value(id.name)
|
|
389
|
+
}, resolve_member_access: lambda { |ma|
|
|
390
|
+
if (receiver_type = resolve_type_expression(ma.receiver))
|
|
391
|
+
next resolve_enum_member_const_value(receiver_type, ma.member)
|
|
392
|
+
end
|
|
393
|
+
nil
|
|
394
|
+
}, resolve_call: lambda { |inner_call|
|
|
395
|
+
evaluate_compile_time_call(inner_call, scopes:)
|
|
396
|
+
})
|
|
397
|
+
return nil unless val
|
|
398
|
+
fields[argument.name] = val
|
|
399
|
+
end
|
|
400
|
+
return fields
|
|
401
|
+
end
|
|
379
402
|
func = @ctx.top_level_functions[callee_name]
|
|
380
403
|
if func&.ast&.respond_to?(:const) && func.ast.const
|
|
381
404
|
evaluate_const_function_body(func, expression.arguments, scopes:)
|
|
@@ -16,19 +16,11 @@ module MilkTea
|
|
|
16
16
|
severity = error.respond_to?(:severity) ? error.severity : :error
|
|
17
17
|
code = error.respond_to?(:code) ? error.code : nil
|
|
18
18
|
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
source_lines = source.split("\n", -1)
|
|
23
|
-
source_line = source_lines[line - 1] || ""
|
|
24
|
-
stripped = source_line.gsub(/\t/, " ")
|
|
19
|
+
# Strip location suffix from message (errors embed "at path:line:col" in message text)
|
|
20
|
+
location_suffix = " at #{path}:#{line}:#{column}"
|
|
21
|
+
error_message = error_message.delete_suffix(location_suffix).strip
|
|
25
22
|
|
|
26
|
-
|
|
27
|
-
highlight = if length && length > 1
|
|
28
|
-
"^" + "~" * (length - 1)
|
|
29
|
-
else
|
|
30
|
-
"^"
|
|
31
|
-
end
|
|
23
|
+
source ||= read_source(path)
|
|
32
24
|
|
|
33
25
|
bold = color ? "\e[1m" : ""
|
|
34
26
|
red = color ? "\e[31m" : ""
|
|
@@ -46,9 +38,21 @@ module MilkTea
|
|
|
46
38
|
|
|
47
39
|
code_text = code ? "#{cyan}[#{code}]#{reset}" : ""
|
|
48
40
|
|
|
41
|
+
return "#{sev_color}#{sev_text}#{code_text}#{reset}: #{error_message} -- #{path}:#{line}:#{column}" unless source
|
|
42
|
+
|
|
43
|
+
source_lines = source.split("\n", -1)
|
|
44
|
+
source_line = source_lines[line - 1] || ""
|
|
45
|
+
stripped = source_line.gsub(/\t/, " ")
|
|
46
|
+
|
|
47
|
+
indent = " " * [column - 1, 0].max
|
|
48
|
+
highlight = if length && length > 1
|
|
49
|
+
"^" + "~" * (length - 1)
|
|
50
|
+
else
|
|
51
|
+
"^"
|
|
52
|
+
end
|
|
53
|
+
|
|
49
54
|
[
|
|
50
|
-
"#{
|
|
51
|
-
" #{bold}-->#{reset} #{path}:#{line}:#{column}",
|
|
55
|
+
"#{sev_color}#{sev_text}#{code_text}#{reset}: #{error_message} -- #{path}:#{line}:#{column}",
|
|
52
56
|
" #{bold}|#{reset}",
|
|
53
57
|
"#{line.to_s.rjust(5)} #{bold}|#{reset} #{stripped}",
|
|
54
58
|
" #{bold}|#{reset} #{sev_color}#{indent}#{highlight}#{reset}",
|
data/std/mem/ptr.mt
CHANGED
|
@@ -10,3 +10,12 @@ extending ptr[T]:
|
|
|
10
10
|
|
|
11
11
|
public function store(value: T) -> void:
|
|
12
12
|
unsafe: read(this) = value
|
|
13
|
+
|
|
14
|
+
public function load_at(offset: ptr_uint) -> T:
|
|
15
|
+
return unsafe: read(this + offset)
|
|
16
|
+
|
|
17
|
+
public function store_at(offset: ptr_uint, value: T) -> void:
|
|
18
|
+
unsafe: read(this + offset) = value
|
|
19
|
+
|
|
20
|
+
public function cast[U]() -> ptr[U]:
|
|
21
|
+
return unsafe: ptr[U]<-this
|
metadata
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
|
2
2
|
name: mt-lang
|
|
3
3
|
version: !ruby/object:Gem::Version
|
|
4
|
-
version: 0.3.
|
|
4
|
+
version: 0.3.6
|
|
5
5
|
platform: ruby
|
|
6
6
|
authors:
|
|
7
7
|
- Long (Teefan) Tran
|
|
@@ -602,7 +602,7 @@ metadata:
|
|
|
602
602
|
homepage_uri: https://teefan.github.io/mt-lang/
|
|
603
603
|
source_code_uri: https://github.com/teefan/mt-lang
|
|
604
604
|
post_install_message: |
|
|
605
|
-
Milk Tea 0.3.
|
|
605
|
+
Milk Tea 0.3.6 installed!
|
|
606
606
|
|
|
607
607
|
System requirements:
|
|
608
608
|
- A C compiler (gcc or clang) must be available on PATH
|