| summaryrefslogtreecommitdiff |
diff options
| author | Nathanael Sensfelder <SpamShield0@MultiAgentSystems.org> | 2020-08-31 00:44:25 +0200 |
|---|---|---|
| committer | Nathanael Sensfelder <SpamShield0@MultiAgentSystems.org> | 2020-08-31 00:44:25 +0200 |
| commit | 0ebd88472a6bd195f2f5ff34165c7fa79053105d (patch) | |
| tree | 8488f24e7cb16c7ed589703361ce9604c317520a | |
| parent | 23c5a3b1bd89e7a394a4cc4881e0764d601632c7 (diff) | |
Adds more list instr, Blackjack example.
19 files changed, 1223 insertions, 29 deletions
diff --git a/data/examples/blackjack/cards.fate b/data/examples/blackjack/cards.fate new file mode 100644 index 0000000..2312f03 --- /dev/null +++ b/data/examples/blackjack/cards.fate @@ -0,0 +1,116 @@ +(fate_version 1) + +(declare_structure card + ( text name ) + ( int number ) + ( int score ) +) + +(local (list card) heart_cards) +(local (list card) spade_cards) +(local (list card) club_cards) +(local (list card) diamond_cards) + +(define_sequence generate_card_familly ((string name) ((ptr (list card)) deck)) + (local int i) + + (for (set i 1) (=< (var i) 13) (set i (+ (var i) 1)) + (local card c) + + (set c.number (var i)) + + (set c.name + (text + (switch (var i) + (1 Ace) + (11 Jack) + (12 Queen) + (13 Kind) + (cast string (var i)) + ) + of (var name) + ) + ) + + (set c.score + (switch (var i) + (11 10) + (12 10) + (13 10) + (var i) + ) + ) + + (add (var c) (at deck)) + ) +) + +(visit generate_card_familly Hearts (ptr heart_cards)) +(visit generate_card_familly Spades (ptr spade_cards)) +(visit generate_card_familly Diamonds (ptr diamond_cards)) +(visit generate_card_familly Clubs (ptr club_cards)) + +(global (list card) deck_template) + +(add_all heart_cards deck_template) +(add_all spade_cards deck_template) +(add_all diamond_cards deck_template) +(add_all club_cards deck_template) + +(define_sequence shuffle_into_deck + ( + ((ptr (list card)) cards) + ((ptr (list card)) deck) + ) + + (while (! (is_empty (at cards))) + (local int o) + (local int d) + + (set o (rand 0 (- (size (at cards)) 1))) + + (if_else (is_empty (at deck)) + (set d 0) + (set d (rand 0 (- (size (at deck)) 1))) + ) + + (add_at (var d) (access (at cards) (var o)) (at deck)) + (remove_at (var o) (at cards)) + ) +) + +(define_sequence generate_shuffled_deck (((ptr (list card)) result)) + (local (list card) initial_deck) + + (set initial_deck (var deck_template)) + + (clear (at result)) + (visit shuffle_into_deck (ptr initial_deck) (var result)) +) + +(define_sequence draw_a_card (((ptr (list card)) deck) ((ptr card) result)) + (set (at result) (access (at deck) 0)) + (remove_at 0 (at deck)) +) + +(define_sequence compute_score (((ptr (list card)) deck) ((ptr int) result)) + (local int aces_count) + (local int maybe_better_score) + + (set (at result) 0) + + (foreach (at deck) card + (set (at result) (+ (var card.score) (at result))) + (if (= (var card.number) 1) + (set aces_count (+ (var aces_count) 1)) + ) + ) + + (while (> (var aces_count) 0) + (set maybe_better_score (+ (at result) 10)) + (if (=< (var maybe_better_score) 21) + (set (at result) (var maybe_better_score)) + ) + (set aces_count (- (var aces_count) 1)) + ) +) diff --git a/data/examples/blackjack/global.fate b/data/examples/blackjack/global.fate new file mode 100644 index 0000000..9c10c9f --- /dev/null +++ b/data/examples/blackjack/global.fate @@ -0,0 +1,36 @@ +(fate_version 1) + +(require player.fate) + +(global player player) + +(global (lambda text (int)) coins_word) + +(set coins_word + (lambda ((int i)) + (if_else (= (var i) 1) + (text a single coin ) + (text (var i) coins ) + ) + ) +) + +(declare_text_effect action_description) + +(define_sequence money_acquisition ((int amount)) + (set player.money (+ (var player.money) (var amount))) + (if (> (var amount) 0) + (text_effect action_description + You acquired (eval coins_word (var amount))! + ) + ) +) + +(define_sequence money_loss ((int amount)) + (set player.money (- (var player.money) (var amount))) + (if (> (var amount) 0) + (text_effect action_description + You lost (eval coins_word (var amount)). + ) + ) +) diff --git a/data/examples/blackjack/main.fate b/data/examples/blackjack/main.fate new file mode 100644 index 0000000..0b5acf8 --- /dev/null +++ b/data/examples/blackjack/main.fate @@ -0,0 +1,77 @@ +(fate_version 1) + +(require player.fate) +(require global.fate) +(require cards.fate) +(require rules.fate) +(require play.fate) + +(local int original_amount) + +(set player.money 0) + +Welcome to Tonkadur's wonderful and totally original blackjack! +Say, I don't think I've seen you before... +No, no, I am sure I haven't, actually. +(prompt_string player.name 1 64 What's your name, then?) +Alright, (var player.name), well, since it's your first time here, let me give +you some coins. +Just between you and me, someone left those laying around, they aren't mine. + +(visit money_acquisition (+ 100 (rand 0 100))) +(set original_amount (var player.money)) + +Now, you're all set to go... unless you don't know how to play? + +(player_choice + ( + ( As it happens, I do not. ) + (visit rules_of_blackjack) + (text_effect action_description + You leave the counter and approach one of the tables. + ) + (visit play_a_game) + ) + ( + ( I am familiar with BlackJack. ) + (text_effect action_description + You leave the counter and approach one of the tables. + ) + (visit play_a_game) + ) +) +(text_effect action_description + As you leave the establishment, the receptionist notices you. +) + +(cond + ( + (=< (var player.money) (/ (var original_amount) 2)) + Outch. I suppose all your luck was spent by getting these free coins. + ) + ( + (< (var player.money) (var original_amount)) + Well, that's not too bad for your first time. Come back tomorrow, I am + sure you'll be getting it all back. + ) + ( + (< (var player.money) (* (var original_amount) 2)) + Had a good day, I hope? + ) + ( + (< (var player.money) (* (var original_amount) 4)) + Well! That was some fine play, if I do say so myself! + ) + ( + (true) + (var player.name)! How did you do that?! You have to teach me! I did give + you the tools of your success, so please? + ) +) + +(text_effect action_description + You walk out, having turned (eval coins_word (var original_amount)) into + (eval coins_word (var player.money)). +) + +(end) diff --git a/data/examples/blackjack/play.fate b/data/examples/blackjack/play.fate new file mode 100644 index 0000000..4c2913f --- /dev/null +++ b/data/examples/blackjack/play.fate @@ -0,0 +1,293 @@ +(fate_version 1) + +(require player.fate) +(require global.fate) +(require cards.fate) + +(global bool has_played) +(global (list card) current_deck) +(global (list card) dealer_hand) +(global int bet) +(global bool has_doubled) + +(set has_played (false)) + +(define_sequence play_a_game () + (local card new_card) + + (if (not (var has_played)) + (text_effect action_description + Sitting yourself at a table, you see someone rushing to set up the + cards and manage the game. + ) + ) + (if (= (var player.money) 0) + ( + I am sorry, (var player.name), but you appear to have ran out of coins. + (done) + ) + ) + (prompt_integer bet 1 (var player.money) How much would you like to bet?) + (text_effect action_description + The dealer shuffles the cards and starts dealing. + ) + + (newline) + + (visit generate_shuffled_deck (ptr current_deck)) + + (visit draw_a_card (ptr current_deck) (ptr new_card)) + (add (var new_card) player.hand) + + (text_effect action_description + You have been dealt the (var new_card.name). + (newline) + ) + + + (visit draw_a_card (ptr current_deck) (ptr new_card)) + (add (var new_card) dealer_hand) + + (text_effect action_description + The dealer has drawn the (var new_card.name). + (newline) + ) + + (visit draw_a_card (ptr current_deck) (ptr new_card)) + (add (var new_card) player.hand) + + (text_effect action_description + You have been dealt the (var new_card.name). + (newline) + ) + + (newline) + + (visit draw_a_card (ptr current_deck) (ptr new_card)) + (add (var new_card) dealer_hand) + + (text_effect action_description + The dealer has drawn a card, face down. + (newline) + ) + + (visit initial_draw) + + (clear dealer_hand) + + (newline) + Interesting. Would you like to go again? + + (player_choice + ( + ( Yes, please. ) + Very well. + (newline) + (jump_to play_a_game) + ) + ( + ( No, thank you. ) + It was a pleasure to play with you. Farewell. + (newline) + (done) + ) + ) +) + +(define_sequence initial_draw () + (local int dealer_score) + (local int player_score) + + (visit compute_score (ptr dealer_hand) (ptr dealer_score)) + (visit compute_score (ptr player.hand) (ptr player_score)) + + (if (= (var dealer_score) 21) + (ifelse (= (var player_score) 21) + ( + (text_effect action_description + The dealer looks very surprised. + ) + (newline) + Double Blackjack! A tie, then. + (done) + ) + ( + (text_effect action_description + The dealer looks surprised, but happy. + ) + (newline) + Blackjack! Looks like I win, this time. + (visit money_loss (var bet)) + (done) + ) + ) + ) + + (if (= (var player_score) 21) + ( + (text_effect action_description + The dealer looks surprised. + ) + (newline) + Blackjack! Looks like you win, this time. + (newline) + (visit money_acquisition (cast int (* (cast float (var bet)) 1.5))) + (done) + ) + ) + + (player_choice + ( + ( Another card, please. ) + (set has_doubled (false)) + (jump_to acquire_card) + ) + ( + ( I will stand. ) + (jump_to resolve_dealer) + ) + (if (and (>= (var player_score) 9) (<= (var player_score) 11)) + ( + ( Double my bet, I'll only take one card. ) + (set bet (* (var bet) 2)) + (set has_doubled (true)) + (jump_to acquire_card) + ) + ) + ) +) + +(define_sequence acquire_card () + (local card new_card) + (local int player_score) + + (visit draw_a_card (ptr current_deck) (ptr new_card)) + (add (var new_card) player.hand) + + (visit compute_score (ptr player.hand) (ptr player_score)) + + (text_effect action_description + You have been dealt the (var new_card.name). + (newline) + Your hand is currently: + ) + (foreach player.hand card + (text_effect action_description + (newline) + * The (var card.name), worth + (if_else (= (var card.number) 1) + (text 1 or 11 points. ) + (text (var card.score) points. ) + ) + ) + ) + (newline) + + (if (> (var player_score) 21) + ( + (text_effect action_description + The dealer looks disappointed. + ) + (newline) + A bust! What a shame... + (newline) + (visit money_loss (var bet)) + (done) + ) + ) + + (if (var has_doubled) + (jump_to resolve_dealer) + ) + + (player_choice + ( + ( Another card, please. ) + (jump_to acquire_card) + ) + ( + ( This will do. I stand. ) + (jump_to resolve_dealer) + ) + ) +) + +(define_sequence resolve_dealer () + (local int dealer_score) + (local int player_score) + (visit compute_score (ptr dealer_hand) (ptr dealer_score)) + + Very well. I shall now play my turn. + (newline) + + (text_effect action_description + My current hand is: + (newline) + ) + (foreach dealer_hand card + (text_effect action_description + (newline) + * The (var card.name), worth + (if_else (= (var card.number) 1) + (text 1 or 11 points. ) + (text (var card.score) points. ) + ) + ) + ) + (newline) + + (while (< (var dealer_score) 17) + (local card new_card) + + (visit draw_a_card (ptr current_deck) (ptr new_card)) + (add (var new_card) dealer_hand) + + (text_effect action_description + The dealer has drawn the (var new_card.name). + (newline) + ) + + (visit compute_score (ptr dealer_hand) (ptr dealer_score)) + ) + + (if (> (var dealer_score) 21) + ( + (text_effect action_description + The dealer looks disappointed. + ) + (newline) + Ah. It would appear I have gone above the limit. + (newline) + (visit money_acquisition (var bet)) + (done) + ) + ) + + (visit compute_score (ptr player.hand) (ptr player_score)) + + (var player_score) for you, against (var dealer_score) for me. + + (newline) + + (if (= (var player_score) (var dealer_score)) + ( + A tie, then. + (done) + ) + ) + + (if_else (> (var player_score) (var dealer_score)) + ( + Congratulation, you won. + (newline) + (visit money_acquisition (var bet)) + (done) + ) + ( + It would appear I have won this game. + (newline) + (visit money_loss (var bet)) + (done) + ) + ) +) diff --git a/data/examples/blackjack/player.fate b/data/examples/blackjack/player.fate new file mode 100644 index 0000000..7d8b947 --- /dev/null +++ b/data/examples/blackjack/player.fate @@ -0,0 +1,9 @@ +(fate_version 1) + +(require cards.fate) + +(define_structure player + (string name) + (int money) + ((list card) hand) +) diff --git a/data/examples/blackjack/rules.fate b/data/examples/blackjack/rules.fate new file mode 100644 index 0000000..3e4c378 --- /dev/null +++ b/data/examples/blackjack/rules.fate @@ -0,0 +1,5 @@ +(fate_version 1) + +(define_sequence rules_of_blackjack () + TODO +) diff --git a/data/tests/user_inputs.fate b/data/tests/user_inputs.fate new file mode 100644 index 0000000..d238c7f --- /dev/null +++ b/data/tests/user_inputs.fate @@ -0,0 +1,14 @@ +(fate_version 1) + +(local int i) + +(prompt_integer i 0 100 How likely is this test to fail?) +Did you say (var i)? That sounds +(ifelse (=< (var i) 50) ( unreasable ) ( very reasonable indeed)). + +(local string name) +(prompt_string name 0 64 Oh, and what's your name?) + +I see, (var name), you might be on to something there... + +(end) diff --git a/src/core/src/tonkadur/fate/v1/lang/World.java b/src/core/src/tonkadur/fate/v1/lang/World.java index 893b0e6..047f1d5 100644 --- a/src/core/src/tonkadur/fate/v1/lang/World.java +++ b/src/core/src/tonkadur/fate/v1/lang/World.java @@ -284,6 +284,7 @@ public class World //type_collection.add(Type.LIST); //type_collection.add(Type.SET); type_collection.add(Type.STRING); + type_collection.add(Type.RICH_TEXT); } catch (final Throwable t) { diff --git a/src/core/src/tonkadur/fate/v1/lang/computation/IsEmpty.java b/src/core/src/tonkadur/fate/v1/lang/computation/IsEmpty.java new file mode 100644 index 0000000..66d40f0 --- /dev/null +++ b/src/core/src/tonkadur/fate/v1/lang/computation/IsEmpty.java @@ -0,0 +1,97 @@ +package tonkadur.fate.v1.lang.computation; + +import tonkadur.error.ErrorManager; + +import tonkadur.parser.Origin; + +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.ComputationVisitor; +import tonkadur.fate.v1.lang.meta.Computation; + +public class IsEmpty extends Computation +{ + /***************************************************************************/ + /**** MEMBERS **************************************************************/ + /***************************************************************************/ + protected final Computation collection; + + /***************************************************************************/ + /**** PROTECTED ************************************************************/ + /***************************************************************************/ + /**** Constructors *********************************************************/ + protected IsEmpty + ( + final Origin origin, + final Computation collection + ) + { + super(origin, Type.BOOL); + + this.collection = collection; + } + + /***************************************************************************/ + /**** PUBLIC ***************************************************************/ + /***************************************************************************/ + /**** Constructors *********************************************************/ + public static IsEmpty build + ( + final Origin origin, + final Computation collection + ) + throws InvalidTypeException + { + + if (!(collection.get_type() instanceof CollectionType)) + { + ErrorManager.handle + ( + new InvalidTypeException + ( + collection.get_origin(), + collection.get_type(), + Type.COLLECTION_TYPES + ) + ); + } + + return new IsEmpty(origin, collection); + } + + /**** Accessors ************************************************************/ + @Override + public void get_visited_by (final ComputationVisitor cv) + throws Throwable + { + cv.visit_is_empty(this); + } + + public Computation get_collection () + { + return collection; + } + + /**** Misc. ****************************************************************/ + @Override + public String toString () + { + final StringBuilder sb = new StringBuilder(); + + sb.append(origin.toString()); + sb.append("(IsEmpty"); + 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/computation/ValueToRichText.java b/src/core/src/tonkadur/fate/v1/lang/computation/ValueToRichText.java index 43c8371..b21024b 100644 --- a/src/core/src/tonkadur/fate/v1/lang/computation/ValueToRichText.java +++ b/src/core/src/tonkadur/fate/v1/lang/computation/ValueToRichText.java @@ -42,7 +42,11 @@ public class ValueToRichText extends RichTextNode value_base_type = value.get_type().get_base_type(); - if (value_base_type.equals(Type.STRING)) + if + ( + value_base_type.equals(Type.STRING) + || value_base_type.equals(Type.RICH_TEXT) + ) { return new ValueToRichText(value); } diff --git a/src/core/src/tonkadur/fate/v1/lang/instruction/AddElementAt.java b/src/core/src/tonkadur/fate/v1/lang/instruction/AddElementAt.java new file mode 100644 index 0000000..4cd192f --- /dev/null +++ b/src/core/src/tonkadur/fate/v1/lang/instruction/AddElementAt.java @@ -0,0 +1,199 @@ +package tonkadur.fate.v1.lang.instruction; + +import java.util.Collections; + +import tonkadur.error.ErrorManager; + +import tonkadur.parser.Origin; + +import tonkadur.fate.v1.error.ConflictingTypeException; +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; + +public class AddElementAt extends Instruction +{ + /***************************************************************************/ + /**** MEMBERS **************************************************************/ + /***************************************************************************/ + protected final Computation index; + protected final Computation element; + protected final Computation collection; + + /***************************************************************************/ + /**** PROTECTED ************************************************************/ + /***************************************************************************/ + /**** Constructors *********************************************************/ + protected AddElementAt + ( + final Origin origin, + final Computation index, + final Computation element, + final Computation collection + ) + { + super(origin); + + this.index = index; + this.collection = collection; + this.element = element; + } + + /***************************************************************************/ + /**** PUBLIC ***************************************************************/ + /***************************************************************************/ + /**** Constructors *********************************************************/ + public static AddElementAt build + ( + final Origin origin, + final Computation index, + final Computation element, + final Computation collection + ) + throws + InvalidTypeException, + ConflictingTypeException, + IncomparableTypeException + { + final Type hint; + final Type collection_type; + final CollectionType collection_true_type; + final Type collection_element_type; + + collection_type = collection.get_type(); + + if + ( + (!(collection_type instanceof CollectionType)) + || (((CollectionType) collection_type).is_set()) + ) + { + ErrorManager.handle + ( + new InvalidTypeException + ( + collection.get_origin(), + collection.get_type(), + Collections.singletonList(Type.LIST) + ) + ); + } + + if (!index.get_type().can_be_used_as(Type.INT)) + { + ErrorManager.handle + ( + new InvalidTypeException + ( + index.get_origin(), + index.get_type(), + Collections.singletonList(Type.INT) + ) + ); + } + + collection_true_type = (CollectionType) collection_type; + collection_element_type = collection_true_type.get_content_type(); + + if + ( + element.get_type().can_be_used_as(collection_element_type) + || + (element.get_type().try_merging_with(collection_element_type) != null) + ) + { + return new AddElementAt(origin, index, element, collection); + } + + ErrorManager.handle + ( + new ConflictingTypeException + ( + element.get_origin(), + element.get_type(), + collection_element_type + ) + ); + + hint = + (Type) element.get_type().generate_comparable_to + ( + collection_element_type + ); + + if (hint.equals(Type.ANY)) + { + ErrorManager.handle + ( + new IncomparableTypeException + ( + element.get_origin(), + element.get_type(), + collection_element_type + ) + ); + } + + return new AddElementAt(origin, index, element, collection); + } + + /**** Accessors ************************************************************/ + @Override + public void get_visited_by (final InstructionVisitor iv) + throws Throwable + { + iv.visit_add_element_at(this); + } + + public Computation get_collection () + { + return collection; + } + + public Computation get_index () + { + return index; + } + + public Computation get_element () + { + return element; + } + + /**** Misc. ****************************************************************/ + @Override + public String toString () + { + final StringBuilder sb = new StringBuilder(); + + sb.append("(AddElementAt"); + 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("element:"); + sb.append(System.lineSeparator()); + sb.append(element.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/AddElementsOf.java b/src/core/src/tonkadur/fate/v1/lang/instruction/AddElementsOf.java new file mode 100644 index 0000000..7409b2b --- /dev/null +++ b/src/core/src/tonkadur/fate/v1/lang/instruction/AddElementsOf.java @@ -0,0 +1,170 @@ +package tonkadur.fate.v1.lang.instruction; + +import tonkadur.error.ErrorManager; + +import tonkadur.parser.Origin; + +import tonkadur.fate.v1.error.ConflictingTypeException; +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.Reference; + +public class AddElementsOf extends Instruction +{ + /***************************************************************************/ + /**** MEMBERS **************************************************************/ + /***************************************************************************/ + protected final Reference other_collection; + protected final Reference collection; + + /***************************************************************************/ + /**** PROTECTED ************************************************************/ + /***************************************************************************/ + /**** Constructors *********************************************************/ + protected AddElementsOf + ( + final Origin origin, + final Reference other_collection, + final Reference collection + ) + { + super(origin); + + this.collection = collection; + this.other_collection = other_collection; + } + + /***************************************************************************/ + /**** PUBLIC ***************************************************************/ + /***************************************************************************/ + /**** Constructors *********************************************************/ + public static AddElementsOf build + ( + final Origin origin, + final Reference other_collection, + final Reference collection + ) + throws + InvalidTypeException, + ConflictingTypeException, + IncomparableTypeException + { + final Type hint; + final Type collection_type, other_collection_type; + + collection_type = collection.get_type(); + other_collection_type = other_collection.get_type(); + + if (!(collection_type instanceof CollectionType)) + { + ErrorManager.handle + ( + new InvalidTypeException + ( + collection.get_origin(), + collection_type, + Type.COLLECTION_TYPES + ) + ); + } + + if (!(other_collection_type instanceof CollectionType)) + { + ErrorManager.handle + ( + new InvalidTypeException + ( + other_collection.get_origin(), + other_collection_type, + Type.COLLECTION_TYPES + ) + ); + } + + if (other_collection_type.can_be_used_as(collection_type)) + { + return new AddElementsOf(origin, other_collection, collection); + } + + ErrorManager.handle + ( + new ConflictingTypeException + ( + other_collection.get_origin(), + other_collection_type, + collection_type + ) + ); + + hint = + (Type) other_collection.get_type().generate_comparable_to + ( + collection_type + ); + + if (hint.equals(Type.ANY)) + { + ErrorManager.handle + ( + new IncomparableTypeException + ( + other_collection.get_origin(), + other_collection_type, + collection_type + ) + ); + } + + return new AddElementsOf(origin, other_collection, collection); + } + + /**** Accessors ************************************************************/ + @Override + public void get_visited_by (final InstructionVisitor iv) + throws Throwable + { + iv.visit_add_elements_of(this); + } + + public Reference get_source_collection () + { + return other_collection; + } + + public Reference get_target_collection () + { + return collection; + } + + /**** Misc. ****************************************************************/ + @Override + public String toString () + { + final StringBuilder sb = new StringBuilder(); + + sb.append(origin.toString()); + sb.append("(AddElementsOf"); + sb.append(System.lineSeparator()); + sb.append(System.lineSeparator()); + + sb.append("other_collection:"); + sb.append(System.lineSeparator()); + sb.append(other_collection.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/meta/ComputationVisitor.java b/src/core/src/tonkadur/fate/v1/lang/meta/ComputationVisitor.java index 09b9135..1cdbcf5 100644 --- a/src/core/src/tonkadur/fate/v1/lang/meta/ComputationVisitor.java +++ b/src/core/src/tonkadur/fate/v1/lang/meta/ComputationVisitor.java @@ -52,6 +52,9 @@ public interface ComputationVisitor public void visit_let (final Let n) throws Throwable; + public void visit_is_empty (final IsEmpty n) + throws Throwable; + public void visit_newline (final Newline n) throws Throwable; 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 6e0da72..30acc7d 100644 --- a/src/core/src/tonkadur/fate/v1/lang/meta/InstructionVisitor.java +++ b/src/core/src/tonkadur/fate/v1/lang/meta/InstructionVisitor.java @@ -8,6 +8,12 @@ public interface InstructionVisitor public void visit_add_element (final AddElement ae) throws Throwable; + public void visit_add_element_at (final AddElementAt n) + throws Throwable; + + public void visit_add_elements_of (final AddElementsOf n) + throws Throwable; + public void visit_assert (final Assert a) throws Throwable; diff --git a/src/core/src/tonkadur/fate/v1/parser/FateLexer.g4 b/src/core/src/tonkadur/fate/v1/parser/FateLexer.g4 index 271a766..03014ac 100644 --- a/src/core/src/tonkadur/fate/v1/parser/FateLexer.g4 +++ b/src/core/src/tonkadur/fate/v1/parser/FateLexer.g4 @@ -17,6 +17,8 @@ R_PAREN: ')'; ABS_KW: L_PAREN 'abs'('olute'?) SEP+; ACCESS_KW: L_PAREN 'access' SEP+; ADD_KW: L_PAREN 'add'(US'element')? SEP+; +ADD_AT_KW: L_PAREN 'add'(US'element')?US'at' SEP+; +ADD_ALL_KW: L_PAREN 'add'US'all'(US'elements')? SEP+; AND_KW: L_PAREN ('and'|'/\\') SEP+; ASSERT_KW: L_PAREN 'assert' SEP+; AT_KW: L_PAREN 'at' SEP+; @@ -28,7 +30,7 @@ COUNT_KW: L_PAREN 'count' SEP+; DECLARE_ALIAS_TYPE_KW: L_PAREN ((('declare'|'define'|'def')US(('sub'|'alias')US)?'type')|'typedef') SEP+; DECLARE_DICT_TYPE_KW: L_PAREN -('declare'|'define'|'def')US('dict'|('struct''ure'?))(US'type')? SEP+; + ('declare'|'define'|'def')US('dict'|('struct''ure'?))(US'type')? SEP+; DECLARE_EVENT_TYPE_KW: L_PAREN ('declare'|'define'|'def')US'event'(US'type')? SEP+; DECLARE_TEXT_EFFECT_KW: L_PAREN ('declare'|'define'|'def')US'text'US'effect' SEP+; DECLARE_VARIABLE_KW: L_PAREN 'global' SEP+; @@ -58,6 +60,7 @@ IMPLIES_KW: L_PAREN ('implies'|'=>'|'->') SEP+; INCLUDE_KW: L_PAREN 'include' SEP+; INDEX_OF_KW: L_PAREN ('index'US'of') SEP+; IS_MEMBER_KW: L_PAREN ('is'US'member'|'contains'|'has') SEP+; +IS_EMPTY_KW: L_PAREN 'is'US'empty' SEP+; LOWER_EQUAL_THAN_KW: L_PAREN ('lower'US'equal'US'than'|'=<'|'<='|'le') SEP+; LOWER_THAN_KW: L_PAREN ('lower'US'than'|'<'|'lt') SEP+; LET_KW: L_PAREN 'let' SEP+; diff --git a/src/core/src/tonkadur/fate/v1/parser/FateParser.g4 b/src/core/src/tonkadur/fate/v1/parser/FateParser.g4 index 4c0a7a0..4cf3f8f 100644 --- a/src/core/src/tonkadur/fate/v1/parser/FateParser.g4 +++ b/src/core/src/tonkadur/fate/v1/parser/FateParser.g4 @@ -571,6 +571,37 @@ returns [Instruction result] ); } + | ADD_AT_KW index=value WS+ element=value WS+ value_reference WS* R_PAREN + { + $result = + AddElementAt.build + ( + CONTEXT.get_origin_at + ( + ($ADD_AT_KW.getLine()), + ($ADD_AT_KW.getCharPositionInLine()) + ), + ($index.result), + ($element.result), + ($value_reference.result) + ); + } + + | ADD_ALL_KW source=value_reference WS+ target=value_reference WS* R_PAREN + { + $result = + AddElementsOf.build + ( + CONTEXT.get_origin_at + ( + ($ADD_ALL_KW.getLine()), + ($ADD_ALL_KW.getCharPositionInLine()) + ), + ($source.result), + ($target.result) + ); + } + | END_KW { $result = @@ -2247,6 +2278,20 @@ returns [Computation result]: ); } + | IS_EMPTY_KW value_reference WS* R_PAREN + { + $result = + IsEmpty.build + ( + CONTEXT.get_origin_at + ( + ($IS_EMPTY_KW.getLine()), + ($IS_EMPTY_KW.getCharPositionInLine()) + ), + ($value_reference.result) + ); + } + | INDEX_OF_KW value WS+ value_reference WS* R_PAREN { $result = diff --git a/src/core/src/tonkadur/wyrd/v1/compiler/fate/v1/ComputationCompiler.java b/src/core/src/tonkadur/wyrd/v1/compiler/fate/v1/ComputationCompiler.java index f30d433..996a246 100644 --- a/src/core/src/tonkadur/wyrd/v1/compiler/fate/v1/ComputationCompiler.java +++ b/src/core/src/tonkadur/wyrd/v1/compiler/fate/v1/ComputationCompiler.java @@ -1229,6 +1229,25 @@ implements tonkadur.fate.v1.lang.meta.ComputationVisitor } @Override + public void visit_is_empty + ( + final tonkadur.fate.v1.lang.computation.IsEmpty n + ) + throws Throwable + { + final ComputationCompiler cc; + + cc = new ComputationCompiler(compiler); + + n.get_collection().get_visited_by(cc); + + assimilate(cc); + + result_as_computation = + Operation.equals(new Size(cc.get_address()), Constant.ZERO); + } + + @Override public void visit_index_of_operator ( final tonkadur.fate.v1.lang.computation.IndexOfOperator n 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 deb0772..55ff4a2 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 @@ -23,6 +23,7 @@ import tonkadur.wyrd.v1.lang.computation.Constant; import tonkadur.wyrd.v1.lang.computation.Operation; import tonkadur.wyrd.v1.lang.computation.Address; import tonkadur.wyrd.v1.lang.computation.RelativeAddress; +import tonkadur.wyrd.v1.lang.computation.IfElseComputation; import tonkadur.wyrd.v1.lang.computation.Size; import tonkadur.wyrd.v1.lang.computation.GetLastChoiceIndex; import tonkadur.wyrd.v1.lang.computation.ValueOf; @@ -248,6 +249,128 @@ implements tonkadur.fate.v1.lang.meta.InstructionVisitor } @Override + public void visit_add_elements_of + ( + final tonkadur.fate.v1.lang.instruction.AddElementsOf n + ) + throws Throwable + { + final tonkadur.fate.v1.lang.meta.Instruction as_fate; + + + as_fate = + new tonkadur.fate.v1.lang.instruction.ForEach + ( + n.get_origin(), + n.get_source_collection(), + ".secret var of doom", + Collections.singletonList + ( + tonkadur.fate.v1.lang.instruction.AddElement.build + ( + n.get_origin(), + new tonkadur.fate.v1.lang.computation.VariableReference + ( + n.get_origin(), + new tonkadur.fate.v1.lang.Variable + ( + n.get_origin(), + ( + (tonkadur.fate.v1.lang.type.CollectionType) + n.get_source_collection().get_type() + ).get_content_type(), + ".secret var of doom" + ) + ), + n.get_target_collection() + ) + ) + ); + + as_fate.get_visited_by(this); + } + + @Override + public void visit_add_element_at + ( + final tonkadur.fate.v1.lang.instruction.AddElementAt n + ) + throws Throwable + { + final Address collection_as_address; + final ComputationCompiler index_compiler, element_compiler; + final ComputationCompiler collection_compiler; + final Register index_holder; + + index_holder = compiler.registers().reserve(Type.INT); + + index_compiler = new ComputationCompiler(compiler); + + n.get_index().get_visited_by(index_compiler); + + if (index_compiler.has_init()) + { + result.add(index_compiler.get_init()); + } + + + element_compiler = new ComputationCompiler(compiler); + + n.get_element().get_visited_by(element_compiler); + + if (element_compiler.has_init()) + { + result.add(element_compiler.get_init()); + } + + collection_compiler = new ComputationCompiler(compiler); + + n.get_collection().get_visited_by(collection_compiler); + + if (collection_compiler.has_init()) + { + result.add(collection_compiler.get_init()); + } + + result.add + ( + new SetValue + ( + index_holder.get_address(), + new IfElseComputation + ( + Operation.greater_than + ( + index_compiler.get_computation(), + new Size(collection_compiler.get_address()) + ), + new Size(collection_compiler.get_address()), + index_compiler.get_computation() + ) + ) + ); + + result.add + ( + InsertAt.generate + ( + compiler.registers(), + compiler.assembler(), + index_holder.get_address(), + element_compiler.get_computation(), + new Size(collection_compiler.get_address()), + collection_compiler.get_address() + ) + ); + + compiler.registers().release(index_holder); + + index_compiler.release_registers(); + element_compiler.release_registers(); + collection_compiler.release_registers(); + } + + @Override public void visit_add_element ( final tonkadur.fate.v1.lang.instruction.AddElement ae 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 177be18..3792080 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 @@ -176,32 +176,6 @@ public class TypeCompiler return MapType.MAP_TO_INT; } - if (fate_content_type instanceof tonkadur.fate.v1.lang.type.PointerType) - { - return - new MapType - ( - new PointerType - ( - compile - ( - compiler, - ( - (tonkadur.fate.v1.lang.type.PointerType) - fate_content_type - ).get_referenced_type() - ) - ) - ); - } - - System.err.println - ( - "[P] Unknown collection member fate type '" - + fate_content_type - + "'." - ); - - return null; + return new MapType(compile(compiler, fate_content_type)); } } |


