Skip to content

Commit 7fe3a9b

Browse files
committed
feat: append, concat and pop can be used as values
1 parent 6db2011 commit 7fe3a9b

Some content is hidden

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

42 files changed

+292
-8
lines changed

.gitignore

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@ __arkscript__/
1414
/*.ark
1515
*.ark.ir
1616
!tests/unittests/resources/BytecodeReaderSuite/*.arkc
17+
tools/*_hash.py
1718

1819
# Generated files
1920
include/Ark/Constants.hpp

CHANGELOG.md

Lines changed: 2 additions & 0 deletions

include/Ark/Builtins/Builtins.hpp

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -163,6 +163,9 @@ namespace Ark::internal::Builtins
163163
ARK_BUILTIN(at);
164164
ARK_BUILTIN(atAt);
165165
ARK_BUILTIN(type);
166+
ARK_BUILTIN(append_list);
167+
ARK_BUILTIN(concat_list);
168+
ARK_BUILTIN(pop_list);
166169
}
167170
}
168171

src/arkreactor/Builtins/Builtins.cpp

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -134,6 +134,9 @@ namespace Ark::internal::Builtins
134134
{ "head", Value(Operators::head) },
135135
{ "@", Value(Operators::at) },
136136
{ "@@", Value(Operators::atAt) },
137-
{ "type", Value(Operators::type) }
137+
{ "type", Value(Operators::type) },
138+
{ "append", Value(Operators::append_list) },
139+
{ "concat", Value(Operators::concat_list) },
140+
{ "pop", Value(Operators::pop_list) }
138141
};
139142
}

src/arkreactor/Builtins/Operators.cpp

Lines changed: 66 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -374,4 +374,70 @@ namespace Ark::internal::Builtins::Operators
374374

375375
return Value(std::to_string(n[0].valueType()));
376376
}
377+
378+
// cppcheck-suppress constParameterReference
379+
Value append_list(std::vector<Value>& n, VM* vm [[maybe_unused]])
380+
{
381+
if (n.size() < 2 || n[0].valueType() != ValueType::List)
382+
throw types::TypeCheckingError(
383+
"append",
384+
{ { types::Contract {
385+
{ types::Typedef("list", ValueType::List),
386+
types::Typedef("value", ValueType::Any, /* is_variadic= */ true) } } } },
387+
n);
388+
389+
for (Value& e : n | std::ranges::views::drop(1))
390+
n[0].list().push_back(e);
391+
392+
return n[0];
393+
}
394+
395+
// cppcheck-suppress constParameterReference
396+
Value concat_list(std::vector<Value>& n, VM* vm [[maybe_unused]])
397+
{
398+
if (n.size() < 2 || n[0].valueType() != ValueType::List)
399+
throw types::TypeCheckingError(
400+
"concat",
401+
{ { types::Contract {
402+
{ types::Typedef("list", ValueType::List),
403+
types::Typedef("value", ValueType::List, /* is_variadic= */ true) } } } },
404+
n);
405+
406+
for (Value& e : n | std::ranges::views::drop(1))
407+
{
408+
if (e.valueType() != ValueType::List)
409+
throw types::TypeCheckingError(
410+
"concat",
411+
{ { types::Contract {
412+
{ types::Typedef("dst", ValueType::List),
413+
types::Typedef("src", ValueType::List, /* is_variadic= */ true) } } } },
414+
n);
415+
416+
std::ranges::copy(e.list(), std::back_inserter(n[0].list()));
417+
}
418+
419+
return n[0];
420+
}
421+
422+
// cppcheck-suppress constParameterReference
423+
Value pop_list(std::vector<Value>& n, VM* vm [[maybe_unused]])
424+
{
425+
if (!types::check(n, ValueType::List, ValueType::Number))
426+
throw types::TypeCheckingError(
427+
"pop",
428+
{ { types::Contract {
429+
{ types::Typedef("list", ValueType::List),
430+
types::Typedef("index", ValueType::Number) } } } },
431+
n);
432+
433+
long idx = static_cast<long>(n[1].number());
434+
idx = idx < 0 ? static_cast<long>(n[0].list().size()) + idx : idx;
435+
if (std::cmp_greater_equal(idx, n[0].list().size()) || idx < 0)
436+
VM::throwVMError(
437+
ErrorKind::Index,
438+
fmt::format("pop index ({}) out of range (list size: {})", idx, n[0].list().size()));
439+
440+
n[0].list().erase(n[0].list().begin() + idx);
441+
return n[0];
442+
}
377443
}

src/arkreactor/Compiler/Lowerer/ASTLowerer.cpp

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -320,6 +320,10 @@ namespace Ark::internal
320320

321321
if (const auto it_builtin = getBuiltin(name))
322322
page(p).emplace_back(Instruction::BUILTIN, it_builtin.value());
323+
else if (std::ranges::find(Language::UpdateRef, name) != Language::UpdateRef.end())
324+
buildAndThrowError(fmt::format("`{}' updates a list in-place, and can not be used as a value. Prefer using their copy alternative (without the `!` at the end) when possible", name), x);
325+
else if (name == Language::And || name == Language::Or)
326+
buildAndThrowError(fmt::format("`{}' can not be used as a value like `+', where (let add +) (add 1 2) would be valid", name), x);
323327
else if (getOperator(name).has_value())
324328
buildAndThrowError(fmt::format("Found a freestanding operator: `{}`. It can not be used as value like `+', where (let add +) (add 1 2) would be valid", name), x);
325329
else

tests/unittests/resources/CompilerSuite/ir/operators.ark

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -23,4 +23,7 @@
2323
(head [])
2424
(@ [1 2] 1)
2525
(@@ [[1] [2] [3]] 0 0)
26-
(type 12))
26+
(type 12)
27+
(append [] 1)
28+
(concat [1] [2])
29+
(pop [1] 0))

tests/unittests/resources/CompilerSuite/ir/operators.expected

Lines changed: 13 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -66,7 +66,19 @@ page_0
6666
AT_AT 0
6767
LOAD_CONST 3
6868
TYPE 0
69-
CALL_BUILTIN 9, 22
69+
LOAD_CONST 0
70+
LIST 0
71+
APPEND 1
72+
LOAD_CONST 1
73+
LIST 1
74+
LOAD_CONST 0
75+
LIST 1
76+
CONCAT 1
77+
LOAD_CONST 5
78+
LOAD_CONST 0
79+
LIST 1
80+
POP_LIST 0
81+
CALL_BUILTIN 9, 25
7082
.L0:
7183
POP 0
7284
HALT 0
Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1 +1 @@
1-
(print + - * / mod toNumber toString < <= > >= = != not len empty? nil? tail head @ @@ type)
1+
(print + - * / mod toNumber toString < <= > >= = != not len empty? nil? tail head @ @@ type append concat pop)

tests/unittests/resources/CompilerSuite/ir/operators_as_builtins.expected

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,10 @@ page_0
2222
BUILTIN 88
2323
BUILTIN 89
2424
BUILTIN 90
25-
CALL_BUILTIN 9, 22
25+
BUILTIN 91
26+
BUILTIN 92
27+
BUILTIN 93
28+
CALL_BUILTIN 9, 25
2629
.L0:
2730
POP 0
2831
HALT 0

0 commit comments

Comments
 (0)