diff --git a/abra_cli/abra-files/example.abra b/abra_cli/abra-files/example.abra index bee10be9..25c2de3a 100644 --- a/abra_cli/abra-files/example.abra +++ b/abra_cli/abra-files/example.abra @@ -2,5 +2,8 @@ //println([]) val arr = [1, 2, 3, 4] -func sum(acc: Int, i: Int): Int = acc + i -println(arr.reduce(0, sum)) +//func sum(acc: Int, i: Int): Int = acc + i +//println(arr.reduce(0, (acc, i) => acc + i)) + +val fn = (x: Int) => x + 1 +println(fn(123)) diff --git a/abra_core/src/typechecker/typechecker2.rs b/abra_core/src/typechecker/typechecker2.rs index 54176f57..3a0968b6 100644 --- a/abra_core/src/typechecker/typechecker2.rs +++ b/abra_core/src/typechecker/typechecker2.rs @@ -903,7 +903,7 @@ pub enum TypedNode { Invocation { target: Box, arguments: Vec>, type_arg_ids: Vec, type_id: TypeId, resolved_type_id: TypeId }, Accessor { target: Box, kind: AccessorKind, is_opt_safe: bool, member_idx: usize, member_span: Range, type_id: TypeId, type_arg_ids: Vec<(TypeId, Range)>, resolved_type_id: TypeId }, Indexing { target: Box, index: IndexingMode, type_id: TypeId, resolved_type_id: TypeId }, - Lambda { span: Range, func_id: FuncId, type_id: TypeId }, + Lambda { span: Range, func_id: FuncId, type_id: TypeId, resolved_type_id: TypeId }, Assignment { span: Range, kind: AssignmentKind, type_id: TypeId, expr: Box }, If { if_token: Token, condition: Box, condition_binding: Option, if_block: Vec, else_block: Vec, is_statement: bool, type_id: TypeId, resolved_type_id: TypeId }, Match { match_token: Token, target: Box, cases: Vec, is_statement: bool, type_id: TypeId }, @@ -972,7 +972,7 @@ impl TypedNode { TypedNode::NoneValue { resolved_type_id, .. } => *resolved_type_id = new_type_id, TypedNode::Invocation { resolved_type_id, .. } => *resolved_type_id = new_type_id, TypedNode::Accessor { resolved_type_id, .. } => *resolved_type_id = new_type_id, - TypedNode::Lambda { .. } => todo!(), + TypedNode::Lambda { resolved_type_id, .. } => *resolved_type_id = new_type_id, TypedNode::Assignment { .. } => {} TypedNode::Indexing { .. } => {} TypedNode::If { .. } => {} @@ -5384,7 +5384,8 @@ impl<'a, L: LoadModule> Typechecker2<'a, L> { self.end_child_scope(); self.current_function = prev_func_id; - Ok(TypedNode::Lambda { span, func_id: lambda_func_id, type_id: func_type_id }) + let resolved_type_id = type_hint.unwrap_or(func_type_id); + Ok(TypedNode::Lambda { span, func_id: lambda_func_id, type_id: func_type_id, resolved_type_id }) } AstNode::Try(_, _) => todo!(), n => unreachable!("Internal error: node is not an expression: {:?}", n), diff --git a/abra_llvm/src/compiler2.rs b/abra_llvm/src/compiler2.rs index c527552e..84248c88 100644 --- a/abra_llvm/src/compiler2.rs +++ b/abra_llvm/src/compiler2.rs @@ -1438,7 +1438,9 @@ impl<'a> LLVMCompiler2<'a> { _ => unreachable!() } } - TypedNode::Lambda { .. } => todo!(), + TypedNode::Lambda { func_id, resolved_type_id, .. } => { + Some(self.make_function_value(func_id, resolved_type_id, resolved_generics)) + } TypedNode::Assignment { kind, expr, .. } => { let expr_val = self.visit_expression(expr, resolved_generics).unwrap(); diff --git a/abra_llvm/tests/arrays.abra b/abra_llvm/tests/arrays.abra index f85c19ea..a202ac75 100644 --- a/abra_llvm/tests/arrays.abra +++ b/abra_llvm/tests/arrays.abra @@ -1,14 +1,13 @@ // Test raw construction of array -func testRawConstruction() { +(() => { val arr = Array(length: 0, _buffer: Pointer.malloc(1), _capacity: 1) arr.push(12) /// Expect: [12] println(arr) -} -testRawConstruction() +})() // Test array literal construction -func testLiteralConstruction() { +(() => { val emptyArr: Int[] = [] /// Expect: [] println(emptyArr) @@ -28,19 +27,17 @@ func testLiteralConstruction() { val nestedArr = [[1, 2], [3, 4], [5, 6]] /// Expect: [[1, 2], [3, 4], [5, 6]] println(nestedArr) -} -testLiteralConstruction() +})() // Indexing (also Array#get(index: Int)) -func testIndexing() { +(() => { val arr = [1, 2, 3] /// Expect: None 1 2 3 1 2 3 None println(arr[-4], arr[-3], arr[-2], arr[-1], arr[0], arr[1], arr[2], arr[3]) -} -testIndexing() +})() // Range indexing (also Array#getRange(startIndex: Int, endIndex: Int)) -func testRangeIndexing() { +(() => { val arr = [1, 2, 3, 4, 5] /// Expect: [2, 3, 4] [2, 3, 4] @@ -60,11 +57,10 @@ func testRangeIndexing() { /// Expect: [2, 3, 4, 5] [1] println(arr[x:], arr[:x]) -} -testRangeIndexing() +})() // Array#pop -func testArrayPop() { +(() => { val arr = [1, 2, 3] /// Expect: 3 println(arr.pop()) @@ -85,46 +81,50 @@ func testArrayPop() { println(arr.pop()) /// Expect: [] println(arr) -} -testArrayPop() +})() // Array#map func addOne(i: Int): Int = i + 1 func exclaim(i: Int, _: Int, x = "!"): String = "$i$x" -func testArrayMap() { +(() => { val arr = [1, 2, 3, 4] /// Expect: [2, 3, 4, 5] println(arr.map(addOne)) + /// Expect: [2, 3, 4, 5] + println(arr.map(i => i + 1)) /// Expect: [1!, 2!, 3!, 4!] println(arr.map(exclaim)) -} -testArrayMap() + /// Expect: [1!, 2!, 3!, 4!] + println(arr.map((i, _, x = "!") => "$i$x")) +})() // Array#filter func isEven(i: Int): Bool = i % 2 == 0 -func testArrayFilter() { +(() => { val arr = [1, 2, 3, 4] /// Expect: [2, 4] println(arr.filter(isEven)) -} -testArrayFilter() + /// Expect: [2, 4] + println(arr.filter(x => x % 2 == 0)) +})() // Array#reduce func doSum(acc: Int, i: Int): Int = acc + i -func testArrayReduce() { +(() => { val arr = [1, 2, 3, 4] /// Expect: 10 println(arr.reduce(0, doSum)) -} -testArrayReduce() + /// Expect: 10 + println(arr.reduce(0, (acc, i) => acc + i)) +})() // Array#forEach func printItem(item: Int) = println(item) -func testArrayForEach() { +(() => { val arr = [1, 2, 3, 4] /// Expect: 1 @@ -132,15 +132,20 @@ func testArrayForEach() { /// Expect: 3 /// Expect: 4 arr.forEach(printItem) -} -testArrayForEach() + /// Expect: 1 + /// Expect: 2 + /// Expect: 3 + /// Expect: 4 + arr.forEach(i => { + println(i) + }) +})() // Array#join -func testArrayJoin() { +(() => { val arr = [123, 456, 789] /// Expect: 123|456|789 println(arr.join("|")) /// Expect: 123456789 println(arr.join()) -} -testArrayJoin() +})() diff --git a/abra_llvm/tests/strings.abra b/abra_llvm/tests/strings.abra index 8c9a504c..ccefc23b 100644 --- a/abra_llvm/tests/strings.abra +++ b/abra_llvm/tests/strings.abra @@ -1,5 +1,5 @@ // Test raw string construction -func testRawStringConstruction() { +(() => { val s = String.withLength(3) s._buffer.offset(0).store(Byte.fromInt(65)) s._buffer.offset(1).store(Byte.fromInt(66)) @@ -8,17 +8,16 @@ func testRawStringConstruction() { println(s) /// Expect: false println(s.isEmpty()) -} -testRawStringConstruction() +})() -func testLiteralConstruction() { +// Test literal construction +(() => { /// Expect: hello println("hello") -} -testLiteralConstruction() +})() // + operator (also String#concat(other: T, *others: Any[]), with no `others`) -func testPlusOperator() { +(() => { /// Expect: helloworld println("hello" + "world") /// Expect: hello12 12hello @@ -29,27 +28,24 @@ func testPlusOperator() { println("hello" + true, true + "hello") /// Expect: hello[1, 2, 3] [1, 2, 3]hello println("hello" + [1, 2, 3], [1, 2, 3] + "hello") -} -testPlusOperator() +})() // Interpolation (also String#concat(other: T, *others: Any[])) -func testInterpolation() { +(() => { val array = [1, 2, 3] /// Expect: length of [1, 2, 3] is 3 println("length of $array is ${array.length}") -} -testInterpolation() +})() // Indexing (also String#get(index: Int)) -func testIndexing() { +(() => { val s = "abc" /// Expect: | a b c a b c | println("|", s[-4], s[-3], s[-2], s[-1], s[0], s[1], s[2], s[3], "|") -} -testIndexing() +})() // Range indexing (also String#getRange(startIndex: Int, endIndex: Int)) -func testRangeIndexing() { +(() => { val s = "hello" /// Expect: h e l l o @@ -78,11 +74,10 @@ func testRangeIndexing() { /// Expect: ello h println(s[a:], s[:a]) -} -testRangeIndexing() +})() // String#isEmpty -func testIsEmpty() { +(() => { val empty = "" /// Expect: true println(empty.isEmpty()) @@ -90,11 +85,10 @@ func testIsEmpty() { val nonEmpty = "hello" /// Expect: false println(nonEmpty.isEmpty()) -} -testIsEmpty() +})() // String#concat -func testStringConcat() { +(() => { /// Expect: helloworld println("hello".concat("world")) /// Expect: hello12 @@ -107,5 +101,4 @@ func testStringConcat() { println("hello".concat([1, 2, 3])) /// Expect: hello12.3true[1, 2, 3] println("hello".concat(1, 2.3, true, [1, 2, 3])) -} -testStringConcat() +})()