Skip to content

Commit b696423

Browse files
authored
Merge branch 'main' into i-1736
2 parents 61ed583 + d9163ab commit b696423

File tree

238 files changed

+6112
-1032
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

238 files changed

+6112
-1032
lines changed

integration_tests/CMakeLists.txt

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -529,6 +529,7 @@ RUN(NAME test_package_01 LABELS cpython llvm)
529529
RUN(NAME test_pkg_lpdraw LABELS cpython llvm wasm)
530530
RUN(NAME test_pkg_lnn_01 LABELS cpython llvm)
531531
RUN(NAME test_pkg_lnn_02 LABELS cpython llvm)
532+
RUN(NAME test_pkg_lpconvexhull LABELS cpython c)
532533

533534
RUN(NAME generics_01 LABELS cpython llvm c)
534535
RUN(NAME generics_02 LABELS cpython llvm c)
@@ -539,7 +540,6 @@ RUN(NAME generics_list_01 LABELS cpython llvm c)
539540
RUN(NAME test_statistics LABELS cpython llvm)
540541
RUN(NAME test_str_attributes LABELS cpython llvm c)
541542
RUN(NAME kwargs_01 LABELS cpython llvm c)
542-
RUN(NAME test_01_goto LABELS cpython llvm c)
543543

544544
RUN(NAME func_inline_01 LABELS llvm c wasm)
545545
RUN(NAME func_inline_02 LABELS cpython llvm c)
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
from .lpconvexhull_main import convex_hull
Lines changed: 56 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,56 @@
1+
from lpython import i32
2+
from .utils import min, distance
3+
4+
def orientation(p: tuple[i32, i32], q: tuple[i32, i32], r: tuple[i32, i32]) -> i32:
5+
# Function to find the orientation of triplet (p, q, r)
6+
# Returns the following values:
7+
# 0: Colinear
8+
# 1: Clockwise
9+
# 2: Counterclockwise
10+
value: i32 = (q[1] - p[1]) * (r[0] - q[0]) - (q[0] - p[0]) * (r[1] - q[1])
11+
if value == 0:
12+
return 0 # Colinear
13+
elif value > 0:
14+
return 1 # Clockwise
15+
else:
16+
return 2 # Counterclockwise
17+
18+
19+
def convex_hull(points: list[tuple[i32, i32]]) -> list[tuple[i32, i32]]:
20+
"""Finds the convex hull of a set of points.
21+
22+
Args:
23+
points: A list of points.
24+
25+
Returns:
26+
A list of points that form the convex hull.
27+
"""
28+
29+
n: i32 = len(points)
30+
if n < 3:
31+
return [(-1, -1)] # Convex hull not possible
32+
33+
# Find the leftmost point
34+
leftmost: tuple[i32, i32] = min(points)
35+
hull: list[tuple[i32, i32]] = []
36+
37+
p: tuple[i32, i32] = leftmost
38+
39+
while True:
40+
hull.append(p)
41+
q: tuple[i32, i32] = points[0]
42+
43+
r: tuple[i32, i32]
44+
for r in points:
45+
if r == p or r == q:
46+
continue
47+
direction: i32 = orientation(p, q, r)
48+
if direction == 1 or (direction == 0 and distance(p, r) > distance(p, q)):
49+
q = r
50+
51+
p = q
52+
53+
if p == leftmost:
54+
break
55+
56+
return hull
Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,29 @@
1+
from lpython import i32, f64
2+
3+
def min(points: list[tuple[i32, i32]]) -> tuple[i32, i32]:
4+
"""Finds the left-most point in a list of points.
5+
6+
Args:
7+
points: A list of points.
8+
9+
Returns:
10+
The left-most point in the list.
11+
"""
12+
13+
left_most_point: tuple[i32, i32] = points[0]
14+
point: tuple[i32, i32]
15+
for point in points:
16+
if point[0] < left_most_point[0]:
17+
left_most_point = point
18+
19+
return left_most_point
20+
21+
22+
def distance(p: tuple[i32, i32], q: tuple[i32, i32]) -> f64:
23+
# Function to calculate the Euclidean distance between two points
24+
x1: i32; y1: i32
25+
x2: i32; y2: i32
26+
27+
x1, y1 = p
28+
x2, y2 = q
29+
return f64((x2 - x1) ** 2 + (y2 - y1) ** 2) ** 0.5

integration_tests/test_01_goto.py

Lines changed: 0 additions & 35 deletions
This file was deleted.
Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,32 @@
1+
from lpython import Const, i32, f64
2+
3+
from lpdraw import Line, Circle, Clear, Display
4+
from lpconvexhull import convex_hull
5+
from numpy import empty, int32
6+
7+
def plot_graph(polygon: list[tuple[i32, i32]], points: list[tuple[i32, i32]]):
8+
Width: Const[i32] = 500 # x-axis limits [0, 499]
9+
Height: Const[i32] = 500 # y-axis limits [0, 499]
10+
Screen: i32[Height, Width] = empty((Height, Width), dtype=int32)
11+
Clear(Height, Width, Screen)
12+
13+
i: i32
14+
n: i32 = len(polygon)
15+
for i in range(n):
16+
Line(Height, Width, Screen, polygon[i][0], polygon[i][1], polygon[(i + 1) % n][0], polygon[(i + 1) % n][1])
17+
18+
point_size: i32 = 5
19+
for i in range(len(points)):
20+
Circle(Height, Width, Screen, points[i][0], points[i][1], f64(point_size))
21+
22+
Display(Height, Width, Screen)
23+
24+
def main0():
25+
points: list[tuple[i32, i32]] = [(445, 193), (138, 28), (418, 279), (62, 438), (168, 345), (435, 325), (293, 440), (158, 94), (403, 288), (136, 278), (141, 243), (287, 313), (338, 492), (172, 78), (29, 404), (79, 377), (184, 91), (69, 324), (408, 72), (494, 1)]
26+
convex_hull_points: list[tuple[i32, i32]] = convex_hull(points)
27+
# print(convex_hull_points)
28+
plot_graph(convex_hull_points, points)
29+
30+
assert convex_hull_points == [(29, 404), (138, 28), (494, 1), (435, 325), (338, 492), (62, 438)]
31+
32+
main0()

src/bin/lpython.cpp

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -444,7 +444,7 @@ int emit_wat(const std::string &infile,
444444
LCompilers::ASR::TranslationUnit_t* asr = r1.result;
445445

446446
diagnostics.diagnostics.clear();
447-
LCompilers::Result<LCompilers::Vec<uint8_t>> r2 = LCompilers::asr_to_wasm_bytes_stream(*asr, al, diagnostics);
447+
LCompilers::Result<LCompilers::Vec<uint8_t>> r2 = LCompilers::asr_to_wasm_bytes_stream(*asr, al, diagnostics, compiler_options);
448448
std::cerr << diagnostics.render(lm, compiler_options);
449449
if (!r2.ok) {
450450
LCOMPILERS_ASSERT(diagnostics.has_error())
@@ -918,7 +918,7 @@ int compile_to_binary_wasm(
918918

919919
// ASR -> WASM
920920
auto asr_to_wasm_start = std::chrono::high_resolution_clock::now();
921-
LCompilers::Result<int> res = LCompilers::asr_to_wasm(*asr, al, outfile, time_report, diagnostics);
921+
LCompilers::Result<int> res = LCompilers::asr_to_wasm(*asr, al, outfile, time_report, diagnostics, compiler_options);
922922
auto asr_to_wasm_end = std::chrono::high_resolution_clock::now();
923923
times.push_back(std::make_pair("ASR to WASM", std::chrono::duration<double, std::milli>(asr_to_wasm_end - asr_to_wasm_start).count()));
924924
std::cerr << diagnostics.render(lm, compiler_options);
@@ -1065,7 +1065,7 @@ int compile_to_binary_wasm_to_x86(
10651065

10661066
// ASR -> WASM
10671067
auto asr_to_wasm_start = std::chrono::high_resolution_clock::now();
1068-
LCompilers::Result<LCompilers::Vec<uint8_t>> r3 = LCompilers::asr_to_wasm_bytes_stream(*asr, al, diagnostics);
1068+
LCompilers::Result<LCompilers::Vec<uint8_t>> r3 = LCompilers::asr_to_wasm_bytes_stream(*asr, al, diagnostics, compiler_options);
10691069
auto asr_to_wasm_end = std::chrono::high_resolution_clock::now();
10701070
times.push_back(std::make_pair("ASR to WASM", std::chrono::duration<double, std::milli>(asr_to_wasm_end - asr_to_wasm_start).count()));
10711071
std::cerr << diagnostics.render(lm, compiler_options);
@@ -1349,7 +1349,7 @@ EMSCRIPTEN_KEEPALIVE char* emit_wat_from_source(char *input) {
13491349
out = diagnostics.render(lm, compiler_options);
13501350
if (asr.ok) {
13511351
LCompilers::Result<LCompilers::Vec<uint8_t>>
1352-
wasm = LCompilers::asr_to_wasm_bytes_stream(*asr.result, al, diagnostics);
1352+
wasm = LCompilers::asr_to_wasm_bytes_stream(*asr.result, al, diagnostics, compiler_options);
13531353
out = diagnostics.render(lm, compiler_options);
13541354
if (wasm.ok) {
13551355
LCompilers::Result<std::string>
@@ -1414,7 +1414,7 @@ EMSCRIPTEN_KEEPALIVE char* emit_wasm_from_source(char *input) {
14141414
out = diagnostics.render(lm, compiler_options);
14151415
if (asr.ok) {
14161416
LCompilers::Result<LCompilers::Vec<uint8_t>>
1417-
wasm = LCompilers::asr_to_wasm_bytes_stream(*asr.result, al, diagnostics);
1417+
wasm = LCompilers::asr_to_wasm_bytes_stream(*asr.result, al, diagnostics, compiler_options);
14181418
out = diagnostics.render(lm, compiler_options);
14191419
if (wasm.ok) {
14201420
out = "0"; // exit code

src/libasr/ASR.asdl

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -103,7 +103,8 @@ symbol
103103
| UnionType(symbol_table symtab, identifier name, identifier* dependencies,
104104
identifier* members, abi abi, access access, symbol? parent)
105105
| Variable(symbol_table parent_symtab, identifier name, identifier* dependencies,
106-
intent intent, expr? symbolic_value, expr? value, storage_type storage, ttype type,
106+
intent intent, expr? symbolic_value, expr? value, storage_type storage,
107+
ttype type, symbol? type_declaration,
107108
abi abi, access access, presence presence, bool value_attr)
108109
| ClassType(symbol_table symtab, identifier name, abi abi, access access)
109110
| ClassProcedure(symbol_table parent_symtab, identifier name, identifier? self_argument,
@@ -284,6 +285,7 @@ expr
284285
| DictLen(expr arg, ttype type, expr? value)
285286

286287
| Var(symbol v)
288+
| FunctionParam(int param_number, ttype type, expr? value) --- used in types
287289

288290
| ArrayConstant(expr* args, ttype type, arraystorage storage_format)
289291
| ArrayItem(expr v, array_index* args, ttype type, arraystorage storage_format, expr? value)

src/libasr/CMakeLists.txt

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,7 @@ set(SRC
2828
codegen/wasm_utils.cpp
2929

3030
pass/nested_vars.cpp
31+
pass/where.cpp
3132
pass/param_to_const.cpp
3233
pass/do_loops.cpp
3334
pass/for_all.cpp
@@ -90,7 +91,7 @@ if (WITH_LLVM)
9091
COMPILE_FLAGS -Wno-deprecated-declarations)
9192
endif()
9293
endif()
93-
add_library(asr ${SRC})
94+
add_library(asr STATIC ${SRC})
9495
target_include_directories(asr BEFORE PUBLIC ${libasr_SOURCE_DIR}/..)
9596
target_include_directories(asr BEFORE PUBLIC ${libasr_BINARY_DIR}/..)
9697
if (WITH_BFD)

src/libasr/asdl_cpp.py

Lines changed: 50 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1169,7 +1169,9 @@ class ExprBaseReplacerVisitor(ASDLVisitor):
11691169

11701170
def __init__(self, stream, data):
11711171
self.replace_expr = []
1172+
self.replace_ttype = []
11721173
self.is_expr = False
1174+
self.is_ttype = False
11731175
self.is_product = False
11741176
self.current_expr_copy_variable_count = 0
11751177
super(ExprBaseReplacerVisitor, self).__init__(stream, data)
@@ -1195,16 +1197,32 @@ def visitModule(self, mod):
11951197
self.replace_expr.append(("", 0))
11961198
self.replace_expr.append((" switch(x->type) {", 1))
11971199

1200+
self.replace_ttype.append((" void replace_ttype(ASR::ttype_t* x) {", 0))
1201+
self.replace_ttype.append((" if( !x ) {", 1))
1202+
self.replace_ttype.append((" return ;", 2))
1203+
self.replace_ttype.append((" }", 1))
1204+
self.replace_ttype.append(("", 0))
1205+
self.replace_ttype.append((" switch(x->type) {", 1))
1206+
11981207
super(ExprBaseReplacerVisitor, self).visitModule(mod)
11991208

12001209
self.replace_expr.append((" default: {", 2))
1201-
self.replace_expr.append((' LCOMPILERS_ASSERT_MSG(false, "Duplication of " + std::to_string(x->type) + " expression is not supported yet.");', 3))
1210+
self.replace_expr.append((' LCOMPILERS_ASSERT_MSG(false, "Replacement in " + std::to_string(x->type) + " expression is not supported yet.");', 3))
12021211
self.replace_expr.append((" }", 2))
12031212
self.replace_expr.append((" }", 1))
12041213
self.replace_expr.append(("", 0))
12051214
self.replace_expr.append((" }", 0))
1215+
1216+
self.replace_ttype.append((" default: {", 2))
1217+
self.replace_ttype.append((' LCOMPILERS_ASSERT_MSG(false, "Replacement in " + std::to_string(x->type) + " type is not supported yet.");', 3))
1218+
self.replace_ttype.append((" }", 2))
1219+
self.replace_ttype.append((" }", 1))
1220+
self.replace_ttype.append(("", 0))
1221+
self.replace_ttype.append((" }", 0))
12061222
for line, level in self.replace_expr:
12071223
self.emit(line, level=level)
1224+
for line, level in self.replace_ttype:
1225+
self.emit(line, level=level)
12081226
self.emit("")
12091227
self.emit("};")
12101228

@@ -1215,7 +1233,8 @@ def visitType(self, tp):
12151233

12161234
def visitSum(self, sum, *args):
12171235
self.is_expr = args[0] == 'expr'
1218-
if self.is_expr:
1236+
self.is_ttype = args[0] == 'ttype'
1237+
if self.is_expr or self.is_ttype:
12191238
for tp in sum.types:
12201239
self.visit(tp, *args)
12211240

@@ -1239,12 +1258,21 @@ def make_visitor(self, name, fields):
12391258
self.replace_expr.append((" self().replace_%s(down_cast<ASR::%s_t>(x));" % (name, name), 3))
12401259
self.replace_expr.append((" break;", 3))
12411260
self.replace_expr.append((" }", 2))
1261+
elif self.is_ttype:
1262+
self.replace_ttype.append((" case ASR::ttypeType::%s: {" % name, 2))
1263+
self.replace_ttype.append((" self().replace_%s(down_cast<ASR::%s_t>(x));" % (name, name), 3))
1264+
self.replace_ttype.append((" break;", 3))
1265+
self.replace_ttype.append((" }", 2))
12421266
self.emit("}", 1)
12431267
self.emit("")
12441268

12451269
def visitField(self, field):
12461270
arguments = None
1247-
if field.type == "expr" or field.type == "symbol" or field.type == "call_arg":
1271+
if (field.type == "expr" or
1272+
field.type == "symbol" or
1273+
field.type == "call_arg" or
1274+
field.type == "ttype" or
1275+
field.type == "dimension"):
12481276
level = 2
12491277
if field.seq:
12501278
self.used = True
@@ -1257,15 +1285,29 @@ def visitField(self, field):
12571285
self.emit(" current_expr = current_expr_copy_%d;" % (self.current_expr_copy_variable_count), level + 1)
12581286
self.emit(" }", level)
12591287
self.current_expr_copy_variable_count += 1
1288+
elif field.type == "dimension":
1289+
self.emit(" ASR::expr_t** current_expr_copy_%d = current_expr;" % (self.current_expr_copy_variable_count), level)
1290+
self.emit(" current_expr = &(x->m_%s[i].m_length);" % (field.name), level)
1291+
self.emit(" self().replace_expr(x->m_%s[i].m_length);"%(field.name), level)
1292+
self.emit(" current_expr = current_expr_copy_%d;" % (self.current_expr_copy_variable_count), level)
1293+
self.current_expr_copy_variable_count += 1
1294+
self.emit(" ASR::expr_t** current_expr_copy_%d = current_expr;" % (self.current_expr_copy_variable_count), level)
1295+
self.emit(" current_expr = &(x->m_%s[i].m_start);" % (field.name), level)
1296+
self.emit(" self().replace_expr(x->m_%s[i].m_start);"%(field.name), level)
1297+
self.emit(" current_expr = current_expr_copy_%d;" % (self.current_expr_copy_variable_count), level)
1298+
self.current_expr_copy_variable_count += 1
12601299
self.emit("}", level)
12611300
else:
12621301
if field.type != "symbol":
12631302
self.used = True
1264-
self.emit("ASR::expr_t** current_expr_copy_%d = current_expr;" % (self.current_expr_copy_variable_count), level)
1265-
self.emit("current_expr = &(x->m_%s);" % (field.name), level)
1266-
self.emit("self().replace_%s(x->m_%s);" % (field.type, field.name), level)
1267-
self.emit("current_expr = current_expr_copy_%d;" % (self.current_expr_copy_variable_count), level)
1268-
self.current_expr_copy_variable_count += 1
1303+
if field.type == "ttype":
1304+
self.emit("self().replace_%s(x->m_%s);" % (field.type, field.name), level)
1305+
else:
1306+
self.emit("ASR::expr_t** current_expr_copy_%d = current_expr;" % (self.current_expr_copy_variable_count), level)
1307+
self.emit("current_expr = &(x->m_%s);" % (field.name), level)
1308+
self.emit("self().replace_%s(x->m_%s);" % (field.type, field.name), level)
1309+
self.emit("current_expr = current_expr_copy_%d;" % (self.current_expr_copy_variable_count), level)
1310+
self.current_expr_copy_variable_count += 1
12691311

12701312
class StmtBaseReplacerVisitor(ASDLVisitor):
12711313

0 commit comments

Comments
 (0)