An imperative and functional programming language.
See Build Instructions.
See our AnyDSL/Impala Website.
An imperative and functional programming language
Home Page: https://anydsl.github.io
License: GNU General Public License v3.0
An imperative and functional programming language.
See Build Instructions.
See our AnyDSL/Impala Website.
Impala IR generation fails when an inner function (indirectly) depends on code in the body of the enclosing function. Seems like code for the body is generated after the inner functions are.
fn f(b: bool, i: int) -> int {
fn F() -> ! { r(i-1) }
fn T() -> ! { r(i) }
let ret : fn(int) -> ! = return;
fn r(x: int) -> ! { ret(x) }
if (b) {
T()
} else {
F()
}
}
fn main() -> int {
f(true, 5)
}
Yields the following error:
impala: .../thorin/src/thorin/def.cpp:34: void thorin::Def::set_op(size_t, const thorin::Def*):
Assertion `def && "setting null pointer"' failed.
zsh: abort (core dumped) impala --emit-thorin codegen/bind_ret.impala
When moving lines defining fn F
and fn T
behind fn r
this works.
Note the @ in call to fac; removing it makes the code compile fine
impala: /home/user/anydsl/thorin/src/thorin/be/llvm/llvm.cpp:988: llvm::Type* thorin::CodeGen::convert(const thorin::Type*): Assertion `ret' failed.
Aborted (core dumped)
type char = u8;
type str = [char];
extern "C" {
fn atoi(&str) -> int;
fn print_int(int) -> ();
}
fn subber(a: int, b: int) -> int {
a - b
}
fn invocator(a:fn(int) -> int, b: int) -> int {
a(b)
}
fn fac_rec(n : int, d:explicit_delegate)->int {
if (n <= 0) {
1
} else {
n * fac_rec(d.callable(n), d)
}
}
struct explicit_delegate {
callable: fn(int) -> int
}
fn fac_nrec(n : int, delta: int) -> int {
let subber1 = |x: int| subber(x, delta);
let ci = explicit_delegate{
callable : subber1
};
@fac_rec(n, ci)
}
fn main(argc: int, argv: &[&str]) -> int {
let n = if argc >= 2 { atoi(argv(1)) } else { 1 };
let res = fac_nrec(10, n);
print_int(res);
res
}
Code:
Note there are no specialization annotations (@), adding halt annotations ($) doesnt seem to help either.
fn subber(a: int, b: int) -> int {
a - b
}
fn fac_rec(n : int, muter: fn(int) -> int) -> int {
if (n <= 0) {
1
} else {
let nn = muter(n);
n * $fac_rec(nn, muter)
}
}
fn fac_nrec(n : int) -> int {
let subber1 = |x: int| subber(x, 1);
fac_rec(n, subber1)
}
fn main() -> int {
fac_nrec(5)
//if @fac_rec(5) == 120 { 0 } else { 1 }
}
This same code is trivially runnable in JS console:
(function(){
var s=(a,b)=>a-b;
var s1=(a)=>s(a,1);
function fac_rec(n, muter){
if(n<=0){ return 1} else {return n*fac_rec(muter(n),muter)}
}
console.log(fac_rec(5,s1));
})()
Example:
static foo = bar();
The following code crashes :
type Blob = (i32, i32);
fn blobify(i: i32) -> Blob {
(i, i)
}
fn main() -> () {
let b = blobify(42);
}
Run with -emit-thorin.
The following code types: impala test.impala
struct S1 {
a : i32
}
struct S2 {
a : i32
}
fn get2(a: i32) -> S2 { get1(a) }
fn get1(a: i32) -> S1 { S1 { a : a } }
fn main(i: i32) -> i32 {
get2(i).a
}
But asserts when generating llvm impala -emit-llvm test.impala
:
impala: thorin/src/thorin/util/cast.h:26: L* thorin::scast(R*) [with L = thorin::PrimType; R = thorin::Type]: Assertion `(!r || dynamic_cast<L*>(r)) && "cast not possible"' failed.
Aborted (core dumped)
get2()
returns S2
, but get1()
gives S1
. This should be detected by Sema.
This is not an issue with AnyDSL specifically but rather (I guess) a problem with linking against llvm libs (because of my system setup). I am asking for help in case somebody faced the same problem before.
Today, I had to install some new packages (bumblebee and cuda toolkit) to work on AnyDSL on Linux rather Windows like I used to. During the process, I guess some packages needed to install llvm libs. Running: dnf list installed | grep llvm
, produces the following output:
llvm-libs.i686 3.9.1-2.fc25 @updates
llvm-libs.x86_64 3.9.1-2.fc25 @updates
Now (using the standard AnyDSL installation), when I try to build something using impala (e.g. stincilla), I get the following error:
[ 2%] Generating gaussian.ll
: CommandLine Error: Option 'verify-dom-info' registered more than once!
LLVM ERROR: inconsistency in registered CommandLine options
CMakeFiles/gaussian.dir/build.make:79: recipe for target 'gaussian.ll' failed
According to this (http://lists.llvm.org/pipermail/lldb-dev/2015-March/006852.html), this might be an issue of linking some llvm libs twice.
Does anyone have any pointers on how to resolve this issue?
It would be useful to have a (polymorphic) intrinsic to create bottom values. Something in the lines of:
extern "thorin" {
fn undef[T]() -> T;
}
When compiling the following code with impala (2ab3ab4)
struct CS {
sizes : [i32],
count : i32,
}
fn main() -> i32 {
let cache_sizes = CS {sizes: [32*1024, 256*1024, 20*1024*1024], count: 3}; // in bytes
for i in range(0, cache_sizes.count) {
print_int(cache_sizes.sizes(i));
}
0
}
Impala fails with the following message:
Assertion failed: ((!r || dynamic_cast<L*>(r)) && "cast not possible"), function scast, file dev/anydsl/thorin/src/thorin/util/cast.h, line 26.
Abort trap: 6
I don't see the cast here and the same code works if sizes and count are not in a struct but two local variables.
For the following code the compilation aborts without error message:
type real = f64;
type size_t = u64;
struct vector{
n: size_t,
buf: fn()->Buffer,
set: fn(size_t, real) -> (),
get: fn(size_t) -> real
}
fn get_vector(n: size_t)->vector{
let tmp : Buffer = alloc_cpu(n as i32 * sizeof[real]());
vector{
n: n,
buf: ||{tmp},
set: |i,v|{bitcast[&mut[real]](tmp.data)(i) = v},
get: |i| {bitcast[&[real]](tmp.data)(i)}
}
}
fn loop(lower: size_t, upper: size_t, body: fn(size_t) -> ()) -> () {
if lower < upper {
body(lower);
loop(lower+(1 as size_t), upper, body, return)
}
}
fn main ()->(){
let mut v = get_vector(10 as size_t);
for i in loop (1 as size_t, 10 as size_t ) {
v.set(i, 42.0);
}
}
The problem only occurs if the variable "v" is declared mutable.
Impala flags: -emit-llvm -O3 -log-level error
impala commit 16c3ff7
thorin commit 72e23ec
Hexadecimal constants may result in wrong values under windows (e.g. 0x80000000
results in 2147483647
). This is because the parser relies on the standard library function strtol
, which returns LONG_MAX
in case the number is not representable in 32 bits. In this case 0x80000000
is treated as a positive constant, which explains the returned value.
We have two options:
0x80000000
as a positive number, and emit a warning when an overflow occurs,In the lvalue branch, the type inference rules are broken for field expressions:
const Type* FieldExpr::check(InferSema& sema) const {
auto ltype = sema.check(lhs());
if (is_ptr(ltype)) {
PrefixExpr::create_deref(lhs_.get());
ltype = sema.check(lhs());
}
auto ref = split_ref_type(ltype);
if (auto struct_type = ltype->isa<StructType>()) {
if (auto field_decl = struct_type->struct_decl()->field_decl(symbol())) {
if (ref)
Ref2ValueExpr::create(lhs())->type();
return sema.wrap_ref(ref, struct_type->op(field_decl->index()));
}
}
return sema.wrap_ref(ref, ltype->is_known() ? sema.type_error() : sema.find_type(this));
}
Assuming that the structure type is known, but the field type is not, we will return a type such as reference to ?23
in the first type inference iteration. In the next iteration, we will have inserted a Ref2Value node, which means that lhs
will now have a non-reference type. Hence, this iteration will return a non-reference type as well, which cannot be unified with the type coming from the previous iteration.
This is an example that triggers the bug:
fn iterate_rays(rays: &Ray) -> () {
rays.org;
}
struct Ray {
org: Vec4
}
struct Vec4 {
w: f32
}
My suggestion to fix this issue: Do not create Ref2Value nodes here, as it makes little sense from a type checking perspective (you need a reference to a structure to get a reference to a structure field). This Ref2Value should be located at the usage site, when necessary.
The Impala compiler segfaults on the following minmal example:
struct node {
value : value_t,
left : &node,
right : &node
}
fn post_order_visit(n: &node, visit: fn(value_t) -> ()) -> () {
if(n.left != 0 as &node) { post_order_visit(n.left, visit); }
if(n.right != 0 as &node) { post_order_visit(n.right, visit); }
visit(n.value);
}
extern
fn tree_sum(levels: int) -> value_t {
let tree = ~node{value: 0 as value_t, left: 0 as &node, right: 0 as &node };
let mut sum = 0 as value_t;
post_order_visit(tree, |x| { sum += x; } );
sum
}
This one will also fail:
struct node {
value : value_t,
left : &node,
right : &node
}
fn make_tree(gen: fn() -> value_t, levels: int) -> &node {
if(levels < 1) { return (0 as &node) }
~node { value: gen(),
left: make_tree(gen, levels-1),
right: make_tree(gen, levels-1)
}
}
extern
fn tree_sum(levels: int) -> value_t {
let tree = make_tree(||{0 as value_t}, levels);
0 as value_t;
}
Note that removing the recursive calls will fix it.
The following code leads to correct results with -O2 but wrong with -O3
fn main() -> () {
let N = 4;
let mut A = [N:i32];
let mut B = ~[N:i32];
let mut C = [0, 0, 0, 0];
let mut D = [N:i32];
for i in $range(0, N) {
A(i) = i*i;
B(i) = i*i;
C(i) = i*i;
}
D(0) = 0;
D(1) = 1;
D(2) = 4;
D(3) = 9;
// D(4) = 16; // should break, but doesn't
print_string("A: "); print_array(bitcast[&[i32]](&A), N); print_string("\n");
print_string("B: "); print_array(bitcast[&[i32]]( B), N); print_string("\n");
print_string("C: "); print_array(bitcast[&[i32]](&C), N); print_string("\n");
print_string("D: "); print_array(bitcast[&[i32]](&D), N); print_string("\n");
}
fn print_array(arr: &[i32], num: i32) -> () {
print_string("["); print_int(arr(0));
for i in $range(1, num) {
print_string(", "); print_int(arr(i));
}
print_string("]");
}
Output with -O3:
A: [0, 0, 0, 0]
B: [0, 1, 4, 9]
C: [0, 1, 4, 9]
D: [0, 0, 0, 0]
I'm trying to implement something like the revealing module pattern in my anyDSL application. Unfortunately my implementation causes a segmentation fault
I have prepared a minimal example:
min.cpp:
#include <stdio.h>
#include "min.h" // generated by anyDSL
int main(int arc, char** argv) {
run_adsl();
return 0;
}
min.impala:
extern "C" {
fn printf( &[u8], int ) -> ();
}
extern fn run_adsl() -> () {
let module = myModule();
printf("A) number = %i \n", module.number);
module.increaseNumber(); // If this line is removed the code runs correctly
}
struct Module {
number: int,
increaseNumber: fn() -> ()
}
fn myModule( ) -> ( Module ) {
let mut module = Module {
number: 0,
increaseNumber: | | -> (){ }
};
module.increaseNumber = | | -> (){
module.number++;
};
}
Compilation commands:
impala min.impala -emit-llvm -emit-c-interface
llvm-as min.ll
clang min.cpp min.bc -o min.x
In the minimal example, I create a module
structure which contains a pointer to a function. In the actual implementation of the code, the myModule
function would return different versions of the module
struct with pointers to different functions depending on the inputs passed.
The above code when ran produces the following output:
pupoSDC@xxxx:~/Desktop$ ./hello.x
A) number = 0
A) number = 0
Segmentation fault (core dumped)
Any ideas if I'm doing something wrong, or something that is not supported by the language?
Short Version
Is there any way to convert a reference of type double to a reference of
an array of doubles?
&mut double -> &mut [double]
Long Version
I have a function with the following (simplified) signature:
fn demo( input: &mut [double] ) -> () {
// Irrelevant to the topic
}
I'd like to be able to call this method passing a reference to a cell in an array
which may not be 0. For example, in this minimalist example i want to call
the demo function for the array at entry 3.
fn main( array: &mut [double] ){
demo( &mut array(3), 2 )
}
The above code throws the following error:
error: mismatched types: expected '&mut <infer error: [f64], f64>' but found '&mut f64' as argument type
Please ignore all the memory and segfault risks of this demo code. They were
considered in the full version of the code. Also, I'd like to avoid an approach
where a reference to the array and an integer for the entry are passed to the
demo function. Eg.:
fn demo( input: &mut [double], entry: uint ) -> () {
// Not what i'm looking for.
}
fn main( array: &mut [double] ){
demo( array, 3 )
}
Thank you for your help
This has the implication that we can implicitly cast [4 x int]
to simd[4 x int]
.
We could either change the subclass relation in the C++ implementation or fix is_subtype.
Use either target_compile_features()
or CXX_STANDARD
and CXX_STANDARD_REQUIRED
to select the C++ standard.
Thorin IR created by Impala for @{ expr }
is broken, if expr
returns a value.
Matching a negative number is currently not supported:
fn test(id: i32) -> i32 {
match id {
23 => 42,
-1 => 47,
_ => 11
}
}
impala test.impala
test.impala:4 col 9: error: expected identifier, got '-' while parsing path
test.impala:4 col 9: error: expected '=>', got '-' while parsing pattern of match expression
The following code should not be accepted:
fn main(i : int) -> int {
(|i| i) (1, 2)
}
But Impala accepts it happily (and then breaks during code generation).
There are a number of regressions with the new handling of unit values:
- REQUIRED test failed: codegen/break.impala
- REQUIRED test failed: codegen/continue.impala
- REQUIRED test failed: codegen/fib.impala
- REQUIRED test failed: codegen/fieldexpr.impala
- REQUIRED test failed: codegen/fold.impala
- REQUIRED test failed: codegen/labeled_break.impala
- REQUIRED test failed: codegen/primes_for.impala
- REQUIRED test failed: codegen/range_f.impala
- REQUIRED test failed: codegen/range_l.impala
- REQUIRED test failed: codegen/void_tailcall.impala
- REQUIRED test failed: codegen/zip.impala
- REQUIRED test failed: codegen/benchmarks/aobench.impala
- REQUIRED test failed: codegen/benchmarks/meteor.impala
These are related to calling continuations.
fieldexpr.impala
is an older regression, btw.
The following code:
extern "C" {
fn print_int(i32) -> ();
}
fn main() -> i32 {
let test : i32 = 1 << 31;
print_int(test);
0
}
emits test value as undef while it should be the smallest i32 value.
I noticed a rather strange behavior of my code when using floating point literals with leading decimal points (like .5
for 0.5
). The parser does not complain about the missing number in front of the decimal point, so I assumed that I could just omit any leading zero (like in many other languages). However, the actual number being parsed from .5
is actually 5.0
rather than 0.5
. This looks like the decimal point is just used for type checking here but ignored when parsing the number.
Example code:
print_string(".5 == 0.5 ? ");
if .5 == 0.5 {
print_string("true\n");
} else {
print_string("false\n");
}
print_string(".5 == 5.0 ? ");
if .5 == 5.0 {
print_string("true\n");
} else {
print_string("false\n");
}
Output:
.5 == 0.5 ? false
.5 == 5.0 ? true
Hi,
the following code does not compile for me, except if i change the condition of the while loop to something that is not 'true'. I am using the master branch version.
Code:
fn circular_iteration(sizeLog2 : u64, mut idx : u64, body: fn(u64, fn())) -> () {
let mask = (1u64 << sizeLog2) - 1u64;
while true { // this true is triggering the problem
body(idx);
idx = (idx + 1u64) & mask;
}
}
fn main() -> bool {
for i in circular_iteration(8u64, 42u64) {
if i == 23u64 {
break()
}
thorin_print_long(i as i64);
thorin_print_string("\n");
}
true
}
Error Message:
impala: /home/srichter/anydsl/anydsl/thorin/src/thorin/analyses/scope.cpp:210: void thorin::Scope::build_rev_rpo(thorin::Array<thorin::Lambda*>): Assertion `n == 0' failed.
The following example should be rejected by the type system:
enum Direction { Left, Right };
fn get_direction(dir: i32, body: fn(Direction) -> ()) -> () {
if dir == 0 {
body(Direction::Left)
} else {
(|a| body(a)) (1)
}
}
However, it passes and fails only in the verify phase later on:
Assertion 'c == a' failed in /space/membarth/projects/anydsl/thorin/src/thorin/continuation.h:171 continuation 'lambda_25' calls 'body_9' of type 'fn(mem, Direction, fn(mem))' but call has type 'fn(mem, qs32, fn(mem))'
Many tests for impala are broken because we currently print types such as fn(i32) -> i32
as fn(i32, fn(i32))
. The code that did the pretty printing previously is now commented out in src/impala/sema/type.cpp. Should we change the tests and get a rid of the commented code, or should we re-enable the pretty printing ?
The following piece of code generates a type checking error, even though it should be accepted:
fn main() -> i32 {
let id = |x| x;
id(1i32) + id(1i32)
}
The following code generates an assertion at /impala/src/impala/sema/unifiable.h, Line 529:
fn f1[T](input: T) -> () {}
fn f2[T](input: T) -> () {}
Hi,
For the unroll.impala test, if I add a version of range() after a call to @ range it is still doing partial evaluation. Is this expected?
let unroll = 10;
for i in @range(0, unroll) {
arr(0) = foo(i);
}
for i in range(0, unroll) { // Is being evaluated
arr(0) = foo(i);
}
Depending on the order of function declarations, impala emits correct error messages or segfaults.
Correct error message:
fn a(a: i32) -> () { }
fn b() -> () { }
fn main() -> () {
a(b)
}
test.impala:4 col 7 - 8: error: mismatched types: expected 'i32' but found 'fn(fn())' as argument type
Segfault:
fn a(a: i32) -> () { }
fn main() -> () {
a(b)
}
fn b() -> () { }
Assertion failed: ((!r || dynamic_cast<L*>(r)) && "cast not possible"), function scast, file thorin/src/thorin/util/cast.h, line 26.
Abort trap: 6
In both cases, the error message should be returned.
The following code should not be accepted by Impala :
extern "C" {
fn plausible_number() -> i32;
fn print_number(i32) -> ();
}
fn this_function(a: i32, b: i32, c: fn (i32, i32) -> ()) -> () {
c(a + b, plausible_number());
}
extern fn lolz(k: i32) -> () {
for i in this_function(0, k) { // Should not be accepted : 'c' takes 2 parameters in function 'broken'
print_number(i)
}
}
The dump
method has been removed from Unifiable
(or is it missing?), but the prototype is still present in unifiable.h
.
Hello,
I'm sorry if this is not an impala issue. I have the following code:
struct Data {
item: i32,
}
extern fn foo(arr: &[Data], i: i32) -> () {
let f = @ |i| arr(i);
cpu_prefetch(&f(i) as &u8, 0, 3, 1)
}
extern fn bar(arr: &[Data], i: i32) -> () {
cpu_prefetch(&arr(i) as &u8, 0, 3, 1)
}
Which yields the following result (latest commits on mem2reg branch of impala and thorin):
0000000000001130 <foo>:
1130: movslq %esi,%rax
1133: mov (%rdi,%rax,4),%eax
1136: mov %eax,-0x8(%rsp)
113a: prefetcht0 -0x8(%rsp)
113f: retq
0000000000001140 <bar>:
1140: movslq %esi,%rax
1143: prefetcht0 (%rdi,%rax,4)
1147: retq
1148: nopl 0x0(%rax,%rax,1)
I would expect f
to inline and the code for both functions to be the same. Instead, data gets copied on the stack before the prefetch, which makes the latter useless.
I improved the example from #58 a bit more :)
fn subber(a: int, b: int) -> int {
a - b
}
fn invocator[T, TR](a:fn(T) -> TR, b: T) -> TR {
a(b)
}
fn fac_rec(n : int, muter: fn(int) -> int) -> int {
let swrap = |x: int| invocator(muter,x);
if (n <= 0) {
1
} else {
let nn = swrap(n);
n * fac_rec(nn, swrap)
}
}
fn fac_nrec(n : int) -> int {
let subber1 = |x: int| subber(x, 1);
@fac_rec(n, subber1)
}
fn main() -> int {
fac_nrec(5)
//if @fac_rec(5) == 120 { 0 } else { 1 }
}
and this gets me this assertion:
user@linux-thorin:~/anydsl/impala/test$ impala --emit-llvm -O3 codegen/fac_rec.impala
impala: /home/user/anydsl/impala/src/impala/emit.cpp:539: virtual const thorin::Def* impala::TypeAppExpr::remit(impala::CodeGen&) const: Assertion `false && "TODO"' failed.
Aborted (core dumped)
... and i'm not really sure whether this is a bug or i'm trying to compile something strange :)
UPD: specifying concrete types gets rid of assertion, i'm impressed.
fn fun(&[1]f32) -> () { }
fn main(a: &[1][f32]) -> () {
fun(&a(0))
}
test.impala:4 col 9 - 14: error: mismatched types: expected '&[1]f32' but found '&f32' as argument type
This one never finishes too ;)
Object encoding via recursive record as in [Cardelli 1984]
type char = u8;
type str = [char];
extern "C" {
fn atoi(&str) -> int;
fn print_int(int) -> ();
}
struct MyInt {
get: fn() -> int,
set: fn(int) -> MyInt,
bump: fn() -> MyInt
}
fn makeInt(a: int) -> MyInt {
MyInt {
get: || a,
set: |a2| makeInt(a2),
bump: || makeInt(a-1)
}
}
fn fac_oo(n : MyInt)->MyInt {
if (n.get() <= 0) {
makeInt(1)
} else {
let dec = n.bump();
makeInt(n.get() * fac_oo(dec).get())
}
}
fn fac_wrap(n : int) -> int {
fac_oo(makeInt(n)).get()
}
fn main(argc: int, argv: &[&str]) -> int {
let n = if argc >= 2 { atoi(argv(1)) } else { 6 };
let res = fac_wrap(n);
print_int(res);
res
}
Add documentation in the wiki.
See also issue AnyDSL/thorin#63
Impala segfaults on windows for the following code:
fn @scalar(f: f32) -> f32 { f }
fn main() -> i32 {
let mut value = 1.f;
if 1.f < scalar(0.01f) || 0.2f < scalar(0.01f) || 0.3f < scalar(0.01f) {
value = 0.7f;
}
if value == 1.0f { 0 } else { 1 }
}
Generated thorin code:
main_10(mem mem_11, fn(mem, qs32) return_12) extern @(bool 0, bool 0)
(mem, frame) _20 = enter mem_11
mem _21 = extract _20, qu32 0
frame _22 = extract _20, qu32 1
pf32* value_24 = slot _22
mem value_25 = store _21, value_24, pf32 1
scalar_6(value_25, pf32 0.01, scalar_cont_42)
scalar_cont_42(mem mem_43, pf32 scalar_44)
bool _45 = lt pf32 1, scalar_44
br_1(_45, or_lhs_t_36, or_lhs_f_37)
or_lhs_f_37()
scalar_6(mem_43, pf32 0.01, scalar_cont_47)
scalar_cont_47(mem mem_48, pf32 scalar_49)
bool _50 = lt pf32 0.2, scalar_49
or_result_38(mem_48, _50)
or_lhs_t_36()
or_result_38(mem_48, bool 1)
or_result_38(mem mem_39, bool or_result_40)
br_1(or_result_40, or_lhs_t_31, or_lhs_f_32)
or_lhs_f_32()
scalar_6(mem_39, pf32 0.01, scalar_cont_52)
scalar_cont_52(mem mem_53, pf32 scalar_54)
bool _55 = lt pf32 0.3, scalar_54
or_result_33(mem_53, _55)
or_lhs_t_31()
or_result_33(mem_53, bool 1)
or_result_33(mem mem_34, bool or_result_35)
br_1(or_result_35, if_then_26, if_else_27)
if_else_27()
if_join_28(mem_34, tuple ())
if_then_26()
mem _57 = store mem_34, value_24, pf32 0.7
if_join_28(_57, tuple ())
if_join_28(mem mem_29, () if_join_30)
(mem, pf32) _64 = load mem_29, value_24
mem _65 = extract _64, qu32 0
pf32 _66 = extract _64, qu32 1
bool _67 = eq _66, pf32 1
br_1(_67, if_then_59, if_else_60)
if_else_60()
if_join_61(_65, qs32 1)
if_then_59()
if_join_61(_65, qs32 0)
if_join_61(mem mem_62, qs32 if_join_63)
return_12(mem_62, if_join_63)
br_1(bool br_2, fn() br_3, fn() br_4)
scalar_6(mem mem_7, pf32 f_8, fn(mem, pf32) return_9) @(bool 1, bool 1, bool 1)
(mem, frame) _13 = enter mem_7
mem _15 = extract _13, qu32 0
return_9(_15, f_8)
This gives a parse error:
|x||y, z| x + y + z;
There is currently no negation operator in impala. It should be included since it is useful for masks and bit-wise arithmetic (bit shifts are already implemented). The negation sign in C is the tilde ~. We cannot use it here because it is used by owned pointers. What symbol should we use ?
The following code leads to a compiler segfault (impala -emit-thorin):
fn @(bar == 42 as i32) foo(bar: i32) -> () {}
Impala commit 983163f
I want to re-interpret a value as an array of values of a smaller type. For example, an i32 as an array of 4 i8s. Also, the source (big) and target (small) types are polymorphic so the size of the target array is not fixed (in terms of the number of elements rather than the total size in bytes). Can I do that?
A declarative, efficient, and flexible JavaScript library for building user interfaces.
๐ Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. ๐๐๐
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google โค๏ธ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.