| summaryrefslogtreecommitdiff |
diff options
10 files changed, 846 insertions, 16 deletions
diff --git a/src/core/src/tonkadur/fate/v1/lang/instruction/DoWhile.java b/src/core/src/tonkadur/fate/v1/lang/instruction/DoWhile.java new file mode 100644 index 0000000..b4737a7 --- /dev/null +++ b/src/core/src/tonkadur/fate/v1/lang/instruction/DoWhile.java @@ -0,0 +1,109 @@ +package tonkadur.fate.v1.lang.instruction; + +import java.util.Collections; +import java.util.List; + +import tonkadur.error.ErrorManager; + +import tonkadur.parser.Origin; + +import tonkadur.fate.v1.error.InvalidTypeException; + +import tonkadur.fate.v1.lang.type.Type; + +import tonkadur.fate.v1.lang.meta.InstructionVisitor; +import tonkadur.fate.v1.lang.meta.Instruction; +import tonkadur.fate.v1.lang.meta.Computation; + +public class DoWhile extends Instruction +{ + /***************************************************************************/ + /**** MEMBERS **************************************************************/ + /***************************************************************************/ + protected final Computation condition; + protected final List<Instruction> body; + + /***************************************************************************/ + /**** PROTECTED ************************************************************/ + /***************************************************************************/ + /**** Constructors *********************************************************/ + protected DoWhile + ( + final Origin origin, + final Computation condition, + final List<Instruction> body + ) + { + super(origin); + + this.condition = condition; + this.body = body; + } + + /***************************************************************************/ + /**** PUBLIC ***************************************************************/ + /***************************************************************************/ + /**** Constructors *********************************************************/ + public static DoWhile build + ( + final Origin origin, + final Computation condition, + final List<Instruction> body + ) + throws InvalidTypeException + { + if (!condition.get_type().get_base_type().equals(Type.BOOLEAN)) + { + ErrorManager.handle + ( + new InvalidTypeException + ( + condition.get_origin(), + condition.get_type(), + Collections.singleton(Type.BOOLEAN) + ) + ); + } + + return new DoWhile(origin, condition, body); + } + + /**** Accessors ************************************************************/ + @Override + public void get_visited_by (final InstructionVisitor iv) + throws Throwable + { + iv.visit_do_while(this); + } + + public Computation get_condition () + { + return condition; + } + + public List<Instruction> get_body () + { + return body; + } + + /**** Misc. ****************************************************************/ + @Override + public String toString () + { + final StringBuilder sb = new StringBuilder(); + + sb.append("(DoWhile"); + sb.append(System.lineSeparator()); + sb.append(condition.toString()); + + for (final Instruction i: body) + { + sb.append(System.lineSeparator()); + sb.append(i.toString()); + } + + sb.append(")"); + + return sb.toString(); + } +} diff --git a/src/core/src/tonkadur/fate/v1/lang/instruction/For.java b/src/core/src/tonkadur/fate/v1/lang/instruction/For.java new file mode 100644 index 0000000..2b8d478 --- /dev/null +++ b/src/core/src/tonkadur/fate/v1/lang/instruction/For.java @@ -0,0 +1,131 @@ +package tonkadur.fate.v1.lang.instruction; + +import java.util.Collections; +import java.util.List; + +import tonkadur.error.ErrorManager; + +import tonkadur.parser.Origin; + +import tonkadur.fate.v1.error.InvalidTypeException; + +import tonkadur.fate.v1.lang.type.Type; + +import tonkadur.fate.v1.lang.meta.InstructionVisitor; +import tonkadur.fate.v1.lang.meta.Instruction; +import tonkadur.fate.v1.lang.meta.Computation; + +public class For extends Instruction +{ + /***************************************************************************/ + /**** MEMBERS **************************************************************/ + /***************************************************************************/ + protected final Computation condition; + protected final Instruction pre; + protected final List<Instruction> body; + protected final Instruction post; + + /***************************************************************************/ + /**** PROTECTED ************************************************************/ + /***************************************************************************/ + /**** Constructors *********************************************************/ + protected For + ( + final Origin origin, + final Computation condition, + final Instruction pre, + final List<Instruction> body, + final Instruction post + ) + { + super(origin); + + this.condition = condition; + this.pre = pre; + this.body = body; + this.post = post; + } + + /***************************************************************************/ + /**** PUBLIC ***************************************************************/ + /***************************************************************************/ + /**** Constructors *********************************************************/ + public static For build + ( + final Origin origin, + final Computation condition, + final Instruction pre, + final List<Instruction> body, + final Instruction post + ) + throws InvalidTypeException + { + if (!condition.get_type().get_base_type().equals(Type.BOOLEAN)) + { + ErrorManager.handle + ( + new InvalidTypeException + ( + condition.get_origin(), + condition.get_type(), + Collections.singleton(Type.BOOLEAN) + ) + ); + } + + return new For(origin, condition, pre, body, post); + } + + /**** Accessors ************************************************************/ + @Override + public void get_visited_by (final InstructionVisitor iv) + throws Throwable + { + iv.visit_for (this); + } + + public Computation get_condition () + { + return condition; + } + + public Instruction get_pre () + { + return pre; + } + + public Instruction get_post () + { + return post; + } + + public List<Instruction> get_body () + { + return body; + } + + /**** Misc. ****************************************************************/ + @Override + public String toString () + { + final StringBuilder sb = new StringBuilder(); + + sb.append("(For"); + sb.append(System.lineSeparator()); + sb.append(pre.toString()); + sb.append(System.lineSeparator()); + sb.append(condition.toString()); + sb.append(System.lineSeparator()); + sb.append(post.toString()); + + for (final Instruction i: body) + { + sb.append(System.lineSeparator()); + sb.append(i.toString()); + } + + sb.append(")"); + + return sb.toString(); + } +} diff --git a/src/core/src/tonkadur/fate/v1/lang/instruction/ForEach.java b/src/core/src/tonkadur/fate/v1/lang/instruction/ForEach.java new file mode 100644 index 0000000..e7937f7 --- /dev/null +++ b/src/core/src/tonkadur/fate/v1/lang/instruction/ForEach.java @@ -0,0 +1,87 @@ +package tonkadur.fate.v1.lang.instruction; + +import java.util.Collections; +import java.util.List; + +import tonkadur.error.ErrorManager; + +import tonkadur.parser.Origin; + +import tonkadur.fate.v1.error.InvalidTypeException; + +import tonkadur.fate.v1.lang.type.Type; + +import tonkadur.fate.v1.lang.meta.InstructionVisitor; +import tonkadur.fate.v1.lang.meta.Instruction; +import tonkadur.fate.v1.lang.meta.Reference; + +public class ForEach extends Instruction +{ + /***************************************************************************/ + /**** MEMBERS **************************************************************/ + /***************************************************************************/ + protected final Reference collection; + protected final String var_name; + protected final List<Instruction> body; + + /***************************************************************************/ + /**** PUBLIC ***************************************************************/ + /***************************************************************************/ + /**** Constructors *********************************************************/ + public ForEach + ( + final Origin origin, + final Reference collection, + final String var_name, + final List<Instruction> body + ) + { + super(origin); + + this.collection = collection; + this.var_name = var_name; + this.body = body; + } + + /**** Accessors ************************************************************/ + @Override + public void get_visited_by (final InstructionVisitor iv) + throws Throwable + { + iv.visit_for_each(this); + } + + public Reference get_collection () + { + return collection; + } + + public String get_parameter_name () + { + return var_name; + } + + public List<Instruction> get_body () + { + return body; + } + + /**** Misc. ****************************************************************/ + @Override + public String toString () + { + final StringBuilder sb = new StringBuilder(); + + sb.append("(ForEach"); + sb.append(System.lineSeparator()); + sb.append(collection.toString()); + sb.append(System.lineSeparator()); + sb.append(var_name); + sb.append(System.lineSeparator()); + sb.append(body.toString()); + + sb.append(")"); + + return sb.toString(); + } +} diff --git a/src/core/src/tonkadur/fate/v1/lang/instruction/Free.java b/src/core/src/tonkadur/fate/v1/lang/instruction/Free.java new file mode 100644 index 0000000..ee8efae --- /dev/null +++ b/src/core/src/tonkadur/fate/v1/lang/instruction/Free.java @@ -0,0 +1,67 @@ +package tonkadur.fate.v1.lang.instruction; + +import tonkadur.error.ErrorManager; + +import tonkadur.parser.Origin; + +import tonkadur.fate.v1.lang.type.Type; + +import tonkadur.fate.v1.lang.meta.InstructionVisitor; +import tonkadur.fate.v1.lang.meta.Instruction; +import tonkadur.fate.v1.lang.meta.Reference; + +public class Free extends Instruction +{ + /***************************************************************************/ + /**** MEMBERS **************************************************************/ + /***************************************************************************/ + protected final Reference value_reference; + + /***************************************************************************/ + /**** PROTECTED ************************************************************/ + /***************************************************************************/ + /**** Constructors *********************************************************/ + + /***************************************************************************/ + /**** PUBLIC ***************************************************************/ + /***************************************************************************/ + /**** Constructors *********************************************************/ + public Free + ( + final Origin origin, + final Reference value_reference + ) + { + super(origin); + + this.value_reference = value_reference; + } + + /**** Accessors ************************************************************/ + @Override + public void get_visited_by (final InstructionVisitor iv) + throws Throwable + { + iv.visit_free(this); + } + + public Reference get_reference () + { + return value_reference; + } + + /**** Misc. ****************************************************************/ + @Override + public String toString () + { + final StringBuilder sb = new StringBuilder(); + + sb.append(origin.toString()); + sb.append("(Free "); + sb.append(value_reference.toString()); + + sb.append(")"); + + return sb.toString(); + } +} diff --git a/src/core/src/tonkadur/fate/v1/lang/instruction/RemoveElementAt.java b/src/core/src/tonkadur/fate/v1/lang/instruction/RemoveElementAt.java new file mode 100644 index 0000000..89d0649 --- /dev/null +++ b/src/core/src/tonkadur/fate/v1/lang/instruction/RemoveElementAt.java @@ -0,0 +1,145 @@ +package tonkadur.fate.v1.lang.instruction; + +import tonkadur.error.ErrorManager; + +import tonkadur.parser.Origin; + +import tonkadur.fate.v1.error.IncomparableTypeException; +import tonkadur.fate.v1.error.InvalidTypeException; + +import tonkadur.fate.v1.lang.type.CollectionType; +import tonkadur.fate.v1.lang.type.Type; + +import tonkadur.fate.v1.lang.meta.InstructionVisitor; +import tonkadur.fate.v1.lang.meta.Instruction; +import tonkadur.fate.v1.lang.meta.Computation; +import tonkadur.fate.v1.lang.meta.Reference; + +public class RemoveElementAt extends Instruction +{ + /***************************************************************************/ + /**** MEMBERS **************************************************************/ + /***************************************************************************/ + protected final Computation index; + protected final Reference collection; + + /***************************************************************************/ + /**** PROTECTED ************************************************************/ + /***************************************************************************/ + /**** Constructors *********************************************************/ + protected RemoveElementAt + ( + final Origin origin, + final Computation index, + final Reference collection + ) + { + super(origin); + + this.collection = collection; + this.index = index; + } + + /***************************************************************************/ + /**** PUBLIC ***************************************************************/ + /***************************************************************************/ + /**** Constructors *********************************************************/ + public static RemoveElementAt build + ( + final Origin origin, + final Computation index, + final Reference collection + ) + throws + InvalidTypeException, + IncomparableTypeException + { + final Type collection_type, hint; + + collection_type = collection.get_type(); + + if + ( + !Type.COLLECTION_TYPES.contains(collection_type.get_base_type()) + || !(collection_type instanceof CollectionType) + ) + { + ErrorManager.handle + ( + new InvalidTypeException + ( + collection.get_origin(), + collection.get_type(), + Type.COLLECTION_TYPES + ) + ); + } + + if (index.get_type().can_be_used_as(Type.INT)) + { + return new RemoveElementAt(origin, index, collection); + } + + hint = + (Type) index.get_type().generate_comparable_to(Type.INT); + + if (hint.equals(Type.ANY)) + { + ErrorManager.handle + ( + new IncomparableTypeException + ( + index.get_origin(), + index.get_type(), + Type.INT + ) + ); + } + + return new RemoveElementAt(origin, index, collection); + } + + /**** Accessors ************************************************************/ + @Override + public void get_visited_by (final InstructionVisitor iv) + throws Throwable + { + iv.visit_remove_element_at(this); + } + + public Computation get_index () + { + return index; + } + + public Reference get_collection () + { + return collection; + } + + /**** Misc. ****************************************************************/ + @Override + public String toString () + { + final StringBuilder sb = new StringBuilder(); + + sb.append(origin.toString()); + sb.append("(RemoveElementAt"); + sb.append(System.lineSeparator()); + sb.append(System.lineSeparator()); + + sb.append("index:"); + sb.append(System.lineSeparator()); + sb.append(index.toString()); + sb.append(System.lineSeparator()); + sb.append(System.lineSeparator()); + + sb.append("collection:"); + sb.append(System.lineSeparator()); + sb.append(collection.toString()); + + sb.append(")"); + + return sb.toString(); + } +} diff --git a/src/core/src/tonkadur/fate/v1/lang/instruction/While.java b/src/core/src/tonkadur/fate/v1/lang/instruction/While.java new file mode 100644 index 0000000..ad5c945 --- /dev/null +++ b/src/core/src/tonkadur/fate/v1/lang/instruction/While.java @@ -0,0 +1,109 @@ +package tonkadur.fate.v1.lang.instruction; + +import java.util.Collections; +import java.util.List; + +import tonkadur.error.ErrorManager; + +import tonkadur.parser.Origin; + +import tonkadur.fate.v1.error.InvalidTypeException; + +import tonkadur.fate.v1.lang.type.Type; + +import tonkadur.fate.v1.lang.meta.InstructionVisitor; +import tonkadur.fate.v1.lang.meta.Instruction; +import tonkadur.fate.v1.lang.meta.Computation; + +public class While extends Instruction +{ + /***************************************************************************/ + /**** MEMBERS **************************************************************/ + /***************************************************************************/ + protected final Computation condition; + protected final List<Instruction> body; + + /***************************************************************************/ + /**** PROTECTED ************************************************************/ + /***************************************************************************/ + /**** Constructors *********************************************************/ + protected While + ( + final Origin origin, + final Computation condition, + final List<Instruction> body + ) + { + super(origin); + + this.condition = condition; + this.body = body; + } + + /***************************************************************************/ + /**** PUBLIC ***************************************************************/ + /***************************************************************************/ + /**** Constructors *********************************************************/ + public static While build + ( + final Origin origin, + final Computation condition, + final List<Instruction> body + ) + throws InvalidTypeException + { + if (!condition.get_type().get_base_type().equals(Type.BOOLEAN)) + { + ErrorManager.handle + ( + new InvalidTypeException + ( + condition.get_origin(), + condition.get_type(), + Collections.singleton(Type.BOOLEAN) + ) + ); + } + + return new While(origin, condition, body); + } + + /**** Accessors ************************************************************/ + @Override + public void get_visited_by (final InstructionVisitor iv) + throws Throwable + { + iv.visit_while(this); + } + + public Computation get_condition () + { + return condition; + } + + public List<Instruction> get_body () + { + return body; + } + + /**** Misc. ****************************************************************/ + @Override + public String toString () + { + final StringBuilder sb = new StringBuilder(); + + sb.append("(While"); + sb.append(System.lineSeparator()); + sb.append(condition.toString()); + + for (final Instruction i: body) + { + sb.append(System.lineSeparator()); + sb.append(i.toString()); + } + + sb.append(")"); + + return sb.toString(); + } +} diff --git a/src/core/src/tonkadur/fate/v1/lang/meta/InstructionVisitor.java b/src/core/src/tonkadur/fate/v1/lang/meta/InstructionVisitor.java index fc542bd..ef3fe3e 100644 --- a/src/core/src/tonkadur/fate/v1/lang/meta/InstructionVisitor.java +++ b/src/core/src/tonkadur/fate/v1/lang/meta/InstructionVisitor.java @@ -11,6 +11,24 @@ public interface InstructionVisitor public void visit_assert (final Assert a) throws Throwable; + public void visit_free (final Free n) + throws Throwable; + + public void visit_while (final While n) + throws Throwable; + + public void visit_do_while (final DoWhile n) + throws Throwable; + + public void visit_for (final For n) + throws Throwable; + + public void visit_remove_element_at (final RemoveElementAt n) + throws Throwable; + + public void visit_for_each (final ForEach n) + throws Throwable; + public void visit_clear (final Clear c) throws Throwable; diff --git a/src/core/src/tonkadur/fate/v1/lang/meta/TypedEntryList.java b/src/core/src/tonkadur/fate/v1/lang/meta/TypedEntryList.java index 0002449..d9cee24 100644 --- a/src/core/src/tonkadur/fate/v1/lang/meta/TypedEntryList.java +++ b/src/core/src/tonkadur/fate/v1/lang/meta/TypedEntryList.java @@ -24,6 +24,16 @@ public class TypedEntryList as_list = new ArrayList<TypedEntry>(); } + public void remove (final String name) + { + TypedEntry previous_entry; + + previous_entry = as_map.get(name); + + as_list.remove(previous_entry); + as_map.remove(name); + } + public void add ( final Origin origin, diff --git a/src/core/src/tonkadur/fate/v1/parser/FateParser.g4 b/src/core/src/tonkadur/fate/v1/parser/FateParser.g4 index cd8ca3a..a86ca91 100644 --- a/src/core/src/tonkadur/fate/v1/parser/FateParser.g4 +++ b/src/core/src/tonkadur/fate/v1/parser/FateParser.g4 @@ -26,6 +26,7 @@ options import tonkadur.fate.v1.Utils; import tonkadur.fate.v1.error.IllegalReferenceNameException; + import tonkadur.fate.v1.error.InvalidTypeException; import tonkadur.fate.v1.error.NotInAMacroException; import tonkadur.fate.v1.error.UnknownExtensionContentException; import tonkadur.fate.v1.error.UnknownParameterException; @@ -43,6 +44,7 @@ options Context CONTEXT; World WORLD; TypedEntryList PARAMETERS; + List<Cons<String, Type>> ODD_VARS; } /******************************************************************************/ @@ -54,6 +56,7 @@ fate_file [Context context, World world] CONTEXT = context; WORLD = world; PARAMETERS = null; + ODD_VARS = new ArrayList<Cons<String, Type>>(); } : WS* FATE_VERSION_KW WORD WS* R_PAREN WS* @@ -604,8 +607,7 @@ returns [Instruction result] | REMOVE_AT_KW value WS+ value_reference WS* R_PAREN { - $result = null; - /* + $result = RemoveElementAt.build ( CONTEXT.get_origin_at @@ -616,7 +618,6 @@ returns [Instruction result] ($value.result), ($value_reference.result) ); - */ } | REMOVE_ALL_KW value WS+ value_reference WS* R_PAREN @@ -666,7 +667,16 @@ returns [Instruction result] | FREE_KW value_reference WS* R_PAREN { /* TODO */ - $result = null; + $result = + new Free + ( + CONTEXT.get_origin_at + ( + ($FREE_KW.getLine()), + ($FREE_KW.getCharPositionInLine()) + ), + ($value_reference.result) + ); } | SET_FIELDS_KW value_reference WS* field_value_list WS* R_PAREN @@ -710,26 +720,115 @@ returns [Instruction result] | WHILE_KW value WS* general_fate_sequence WS* R_PAREN { - /* TODO */ - $result = null; + $result = + While.build + ( + CONTEXT.get_origin_at + ( + ($WHILE_KW.getLine()), + ($WHILE_KW.getCharPositionInLine()) + ), + ($value.result), + ($general_fate_sequence.result) + ); } | DO_WHILE_KW value WS* general_fate_sequence WS* R_PAREN { - /* TODO */ - $result = null; + $result = + DoWhile.build + ( + CONTEXT.get_origin_at + ( + ($DO_WHILE_KW.getLine()), + ($DO_WHILE_KW.getCharPositionInLine()) + ), + ($value.result), + ($general_fate_sequence.result) + ); } - | FOR_KW general_fate_instr WS * value WS* general_fate_instr WS* general_fate_sequence WS* R_PAREN + | FOR_KW pre=general_fate_instr WS * value WS* post=general_fate_instr WS* general_fate_sequence WS* R_PAREN { - /* TODO */ - $result = null; + $result = + For.build + ( + CONTEXT.get_origin_at + ( + ($FOR_KW.getLine()), + ($FOR_KW.getCharPositionInLine()) + ), + ($value.result), + ($pre.result), + ($general_fate_sequence.result), + ($post.result) + ); } - | FOR_EACH_KW value_reference WS+ WORD WS+ general_fate_sequence WS* R_PAREN + | FOR_EACH_KW + value_reference WS+ new_reference_name + { + Type collection_type, elem_type; + elem_type = Type.ANY; + + if (PARAMETERS == null) + { + PARAMETERS = new TypedEntryList(); + } + + collection_type = ($value_reference.result).get_type(); + + if (collection_type instanceof CollectionType) + { + elem_type = ((CollectionType) collection_type).get_content_type(); + } + else + { + ErrorManager.handle + ( + new InvalidTypeException + ( + CONTEXT.get_origin_at + ( + ($FOR_EACH_KW.getLine()), + ($FOR_EACH_KW.getCharPositionInLine()) + ), + elem_type, + Type.COLLECTION_TYPES + ) + ); + + elem_type = Type.ANY; + } + + PARAMETERS.add + ( + CONTEXT.get_origin_at + ( + ($FOR_EACH_KW.getLine()), + ($FOR_EACH_KW.getCharPositionInLine()) + ), + elem_type, + ($new_reference_name.result) + ); + } + WS+ general_fate_sequence WS* + R_PAREN { - /* TODO */ - $result = null; + PARAMETERS.remove(($new_reference_name.result)); + + $result = + new ForEach + ( + CONTEXT.get_origin_at + ( + ($FOR_EACH_KW.getLine()), + ($FOR_EACH_KW.getCharPositionInLine()) + ), + ($value_reference.result), + ($new_reference_name.result), + ($general_fate_sequence.result) + ); } | EVENT_KW WORD WS+ value_list WS* R_PAREN @@ -1702,8 +1801,21 @@ returns [Computation result]: | NEW_KW WORD WS* R_PAREN { - /* TODO */ - $result = null; + final Origin origin; + + origin = + CONTEXT.get_origin_at + ( + ($WORD.getLine()), + ($WORD.getCharPositionInLine()) + ); + + $result = + new New + ( + origin, + WORLD.types().get(origin, ($WORD.text)) + ); } ; catch [final Throwable e] 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 5277fd3..ddb5350 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 @@ -343,6 +343,48 @@ implements tonkadur.fate.v1.lang.meta.InstructionVisitor } @Override + public void visit_free (final tonkadur.fate.v1.lang.instruction.Free n) + throws Throwable + { + /* TODO */ + } + + @Override + public void visit_while (final tonkadur.fate.v1.lang.instruction.While n) + throws Throwable + { + /* TODO */ + } + + @Override + public void visit_do_while (final tonkadur.fate.v1.lang.instruction.DoWhile n) + throws Throwable + { + /* TODO */ + } + + @Override + public void visit_for (final tonkadur.fate.v1.lang.instruction.For n) + throws Throwable + { + /* TODO */ + } + + @Override + public void visit_remove_element_at (final tonkadur.fate.v1.lang.instruction.RemoveElementAt n) + throws Throwable + { + /* TODO */ + } + + @Override + public void visit_for_each (final tonkadur.fate.v1.lang.instruction.ForEach n) + throws Throwable + { + /* TODO */ + } + + @Override public void visit_cond_instruction ( final tonkadur.fate.v1.lang.instruction.CondInstruction ci |


