From 8fd556f0065b7a634602cf4a8b666a426d4e8de6 Mon Sep 17 00:00:00 2001 From: Nathanael Sensfelder Date: Sat, 15 Aug 2020 12:35:08 +0200 Subject: Looks like it works. Damn fun to use, too. --- data/tests/lambdas.fate | 60 ++++++++++++++++++++++ .../fate/v1/lang/computation/LambdaExpression.java | 41 +++++++++++++-- src/core/src/tonkadur/fate/v1/lang/type/Type.java | 1 + src/core/src/tonkadur/fate/v1/parser/FateParser.g4 | 27 ++++++++-- .../v1/compiler/fate/v1/InstructionCompiler.java | 6 +++ .../wyrd/v1/compiler/fate/v1/TypeCompiler.java | 10 ++++ 6 files changed, 138 insertions(+), 7 deletions(-) create mode 100644 data/tests/lambdas.fate diff --git a/data/tests/lambdas.fate b/data/tests/lambdas.fate new file mode 100644 index 0000000..654a11c --- /dev/null +++ b/data/tests/lambdas.fate @@ -0,0 +1,60 @@ +(fate_version 1) + +(global (lambda int (int)) int_to_int) + +(set int_to_int + (lambda ( (int i) ) + (+ (var i) 1) + ) +) + +(assert (= 1 (eval int_to_int 0)) FAILED: lambda A) + +(define_sequence map_int_to_int + ( + ((ptr (list int)) out) + ((ptr (list int)) in) + ((lambda int (int)) fun) + ) + (foreach (at in) i + (add (eval fun (var i)) (at out)) + ) +) + +(global (list int) l0) +(global (list int) l1) + +(add 0 l0) +(add 1 l0) +(add 2 l0) +(add 3 l0) +(add 4 l0) +(add 5 l0) + +(visit map_int_to_int (ptr l1) (ptr l0) (var int_to_int)) + +(foreach l0 i + Was (var i) +) + +(foreach l1 i + Is (var i) +) + +(clear l1) + +(visit map_int_to_int + (ptr l1) + (ptr l0) + (lambda ( (int i) ) + (* (eval int_to_int (var i)) 2) + ) +) + +(foreach l1 i + Is (var i) +) + +;;(global (lambda int (int)) times_two) + +(end) diff --git a/src/core/src/tonkadur/fate/v1/lang/computation/LambdaExpression.java b/src/core/src/tonkadur/fate/v1/lang/computation/LambdaExpression.java index 6c99aa4..7ea988b 100644 --- a/src/core/src/tonkadur/fate/v1/lang/computation/LambdaExpression.java +++ b/src/core/src/tonkadur/fate/v1/lang/computation/LambdaExpression.java @@ -1,5 +1,6 @@ package tonkadur.fate.v1.lang.computation; +import java.util.ArrayList; import java.util.List; import tonkadur.parser.Origin; @@ -9,6 +10,9 @@ import tonkadur.fate.v1.lang.meta.Computation; import tonkadur.fate.v1.lang.Variable; +import tonkadur.fate.v1.lang.type.LambdaType; +import tonkadur.fate.v1.lang.type.Type; + public class LambdaExpression extends Computation { /***************************************************************************/ @@ -20,22 +24,51 @@ public class LambdaExpression extends Computation /***************************************************************************/ /**** PROTECTED ************************************************************/ /***************************************************************************/ + protected LambdaExpression + ( + final Origin origin, + final List parameters, + final Computation function, + final Type type + ) + { + super(origin, type); + + this.function = function; + this.parameters = parameters; + } /***************************************************************************/ /**** PUBLIC ***************************************************************/ /***************************************************************************/ /**** Constructors *********************************************************/ - public LambdaExpression + public static LambdaExpression build ( final Origin origin, final List parameters, final Computation function ) { - super(origin, function.get_type()); + final List signature; + final LambdaType type; - this.function = function; - this.parameters = parameters; + signature = new ArrayList(); + + for (final Variable v: parameters) + { + signature.add(v.get_type()); + } + + type = + new LambdaType + ( + origin, + function.get_type(), + "autogen", + signature + ); + + return new LambdaExpression(origin, parameters, function, type); } /**** Accessors ************************************************************/ diff --git a/src/core/src/tonkadur/fate/v1/lang/type/Type.java b/src/core/src/tonkadur/fate/v1/lang/type/Type.java index 92ff859..509bce4 100644 --- a/src/core/src/tonkadur/fate/v1/lang/type/Type.java +++ b/src/core/src/tonkadur/fate/v1/lang/type/Type.java @@ -80,6 +80,7 @@ public class Type extends DeclaredEntity SIMPLE_BASE_TYPES.add(FLOAT); SIMPLE_BASE_TYPES.add(INT); + SIMPLE_BASE_TYPES.add(LAMBDA); SIMPLE_BASE_TYPES.add(STRING); SIMPLE_BASE_TYPES.add(BOOLEAN); SIMPLE_BASE_TYPES.add(REF); diff --git a/src/core/src/tonkadur/fate/v1/parser/FateParser.g4 b/src/core/src/tonkadur/fate/v1/parser/FateParser.g4 index 81b63e2..14accd4 100644 --- a/src/core/src/tonkadur/fate/v1/parser/FateParser.g4 +++ b/src/core/src/tonkadur/fate/v1/parser/FateParser.g4 @@ -418,7 +418,7 @@ catch [final Throwable e] general_fate_instr returns [Instruction result] : - L_PAREN WS+ general_fate_sequence WS* R_PAREN + L_PAREN WS* general_fate_sequence WS* R_PAREN { $result = new InstructionList @@ -1534,6 +1534,27 @@ returns [Type result] ("anonymous (" + ($type.result).get_name() + ") list type") ); } + + | LAMBDA_KW type WS* L_PAREN WS* type_list WS* R_PAREN WS* R_PAREN + { + final Origin start_origin; + + start_origin = + CONTEXT.get_origin_at + ( + ($LAMBDA_KW.getLine()), + ($LAMBDA_KW.getCharPositionInLine()) + ); + + $result = + new LambdaType + ( + start_origin, + ($type.result), + "auto_generated", + ($type_list.result) + ); + } ; catch [final Throwable e] { @@ -2314,7 +2335,7 @@ returns [Computation result] } | LAMBDA_KW - L_PAREN WS+ variable_list WS* R_PAREN + L_PAREN WS* variable_list WS* R_PAREN { final Map variable_map; @@ -2330,7 +2351,7 @@ returns [Computation result] R_PAREN { $result = - new LambdaExpression + LambdaExpression.build ( CONTEXT.get_origin_at ( diff --git a/src/core/src/tonkadur/wyrd/v1/compiler/fate/v1/InstructionCompiler.java b/src/core/src/tonkadur/wyrd/v1/compiler/fate/v1/InstructionCompiler.java index 27f382d..2fe7e43 100644 --- a/src/core/src/tonkadur/wyrd/v1/compiler/fate/v1/InstructionCompiler.java +++ b/src/core/src/tonkadur/wyrd/v1/compiler/fate/v1/InstructionCompiler.java @@ -1763,6 +1763,12 @@ implements tonkadur.fate.v1.lang.meta.InstructionVisitor result.addAll(compiler.registers().store_parameters(parameters)); + /* Terminate current context */ + result.addAll + ( + compiler.registers().get_finalize_context_instructions() + ); + result.addAll ( compiler.registers().get_jump_to_context_instructions diff --git a/src/core/src/tonkadur/wyrd/v1/compiler/fate/v1/TypeCompiler.java b/src/core/src/tonkadur/wyrd/v1/compiler/fate/v1/TypeCompiler.java index 7013e1e..9c20229 100644 --- a/src/core/src/tonkadur/wyrd/v1/compiler/fate/v1/TypeCompiler.java +++ b/src/core/src/tonkadur/wyrd/v1/compiler/fate/v1/TypeCompiler.java @@ -58,6 +58,11 @@ public class TypeCompiler ); } + if (fate_type instanceof tonkadur.fate.v1.lang.type.LambdaType) + { + return Type.INT; + } + fate_type = fate_type.get_base_type(); if (fate_type.equals(tonkadur.fate.v1.lang.type.Type.BOOLEAN)) @@ -166,6 +171,11 @@ public class TypeCompiler return MapType.MAP_TO_RICH_TEXT; } + if (fate_content_type instanceof tonkadur.fate.v1.lang.type.LambdaType) + { + return MapType.MAP_TO_INT; + } + if (fate_content_type instanceof tonkadur.fate.v1.lang.type.PointerType) { return -- cgit v1.2.3-70-g09d2