Skip to content

Commit 4f3337d

Browse files
committed
type_checkers: block
1 parent 5c1d6ec commit 4f3337d

File tree

1 file changed

+98
-0
lines changed

1 file changed

+98
-0
lines changed

src/type_checkers/block.cr

Lines changed: 98 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,98 @@
1+
# -----------------------------------------------------------------------
2+
# This file is part of MoonScript
3+
#
4+
# MoonSript is free software: you can redistribute it and/or modify
5+
# it under the terms of the GNU General Public License as published by
6+
# the Free Software Foundation, either version 3 of the License, or
7+
# (at your option) any later version.
8+
#
9+
# MoonSript is distributed in the hope that it will be useful,
10+
# but WITHOUT ANY WARRANTY; without even the implied warranty of
11+
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12+
# GNU General Public License for more details.
13+
#
14+
# You should have received a copy of the GNU General Public License
15+
# along with MoonSript. If not, see <https://www.gnu.org/licenses/>.
16+
#
17+
# Copyright (C) 2025 Krisna Pranav, MoonScript Developers
18+
# -----------------------------------------------------------------------
19+
20+
module MoonScript
21+
class TypeChecker
22+
def check(node : Ast::Block) : Checkable
23+
if node.expressions.all?(Ast::CssDefinition)
24+
resolve node.expressions
25+
VOID
26+
else
27+
expressions =
28+
node.expressions.select(Ast::Statement)
29+
30+
error! :block_no_expressions do
31+
block "This block doesn't have any statements. It should have at least one."
32+
snippet node
33+
end if expressions.empty?
34+
35+
expressions.dup.tap do |items|
36+
variables = [] of VariableScope
37+
38+
while item = items.shift?
39+
variables.each do |var|
40+
scope.add(node, var[0], var[2])
41+
end
42+
43+
# This is to allow recursion
44+
case target = item.target
45+
when Ast::Variable
46+
case value = item.expression
47+
when Ast::InlineFunction
48+
cache[target] =
49+
static_type_signature(value)
50+
51+
scope.add(item, target.value, target)
52+
end
53+
end
54+
55+
type = resolve item
56+
variables = destructure(item.target, type)
57+
end
58+
end
59+
60+
last =
61+
cache[expressions.last]
62+
63+
error! :statement_last_target do
64+
block do
65+
text "The"
66+
bold "last statement"
67+
text "of a block cannot be an"
68+
bold "assignment:"
69+
end
70+
71+
snippet node
72+
end if expressions.last.target
73+
74+
node.expressions.select(Ast::Statement).each do |item|
75+
next unless return_value = item.return_value
76+
77+
type =
78+
cache[return_value]
79+
80+
error! :statement_return_type_mismatch do
81+
snippet "The type of a return call does not match the return " \
82+
"block:", type
83+
84+
snippet "I was expecting:", last
85+
snippet "It return call in question is here:", return_value
86+
snippet "The value of block:", expressions.last
87+
end unless Comparer.compare(last, type)
88+
end
89+
90+
if async.includes?(node) && last.name != "Promise"
91+
Type.new("Promise", [last] of Checkable)
92+
else
93+
last
94+
end
95+
end
96+
end
97+
end
98+
end

0 commit comments

Comments
 (0)