From 0a239d89edc33e16ff0c11721d40a406c29f75b6 Mon Sep 17 00:00:00 2001 From: Nathanael Sensfelder Date: Sun, 5 Jul 2020 22:28:45 +0200 Subject: Adds Text Effects. --- src/core/src/tonkadur/fate/v1/lang/Event.java | 5 + src/core/src/tonkadur/fate/v1/lang/TextEffect.java | 132 +++++++++++++++++++++ src/core/src/tonkadur/fate/v1/lang/World.java | 56 +++++++-- src/core/src/tonkadur/fate/v1/parser/FateParser.g4 | 104 +++++++++++----- 4 files changed, 261 insertions(+), 36 deletions(-) create mode 100644 src/core/src/tonkadur/fate/v1/lang/TextEffect.java diff --git a/src/core/src/tonkadur/fate/v1/lang/Event.java b/src/core/src/tonkadur/fate/v1/lang/Event.java index d762c71..fe667af 100644 --- a/src/core/src/tonkadur/fate/v1/lang/Event.java +++ b/src/core/src/tonkadur/fate/v1/lang/Event.java @@ -144,6 +144,9 @@ public class Event extends DeclaredEntity { final StringBuilder sb = new StringBuilder(); + sb.append("("); + sb.append(get_type_name()); + sb.append(" "); sb.append(name); if (!signature.isEmpty()) @@ -169,6 +172,8 @@ public class Event extends DeclaredEntity } } + sb.append(")"); + return sb.toString(); } } diff --git a/src/core/src/tonkadur/fate/v1/lang/TextEffect.java b/src/core/src/tonkadur/fate/v1/lang/TextEffect.java new file mode 100644 index 0000000..db29da1 --- /dev/null +++ b/src/core/src/tonkadur/fate/v1/lang/TextEffect.java @@ -0,0 +1,132 @@ +package tonkadur.fate.v1.lang; + +import java.util.ArrayList; +import java.util.List; + +import tonkadur.functional.Merge; + +import tonkadur.parser.Context; +import tonkadur.parser.Location; +import tonkadur.parser.Origin; + +import tonkadur.fate.v1.lang.meta.DeclaredEntity; + +public class TextEffect extends Event +{ + protected static final TextEffect ANY; + + static + { + ANY = + new TextEffect + ( + new Origin(new Context(""), Location.BASE_LANGUAGE), + new ArrayList(), + /* + * Use of a space necessary to avoid conflicting with a user created + * type. + */ + "undetermined text_effect" + ); + } + + public static TextEffect value_on_missing () + { + return ANY; + } + + @Override + public /* static */ String get_type_name () + { + return "TextEffect"; + } + + + /***************************************************************************/ + /**** MEMBERS **************************************************************/ + /***************************************************************************/ + + /***************************************************************************/ + /**** PUBLIC ***************************************************************/ + /***************************************************************************/ + /**** Constructors *********************************************************/ + public TextEffect + ( + final Origin origin, + final List signature, + final String name + ) + { + super(origin, signature, name); + } + + /**** Accessors ************************************************************/ + @Override + public DeclaredEntity generate_comparable_to (final DeclaredEntity de) + { + final List new_signature; + final TextEffect e; + + if (!(de instanceof TextEffect)) + { + return ANY; + } + + e = (TextEffect) de; + + if (signature.size() != e.signature.size()) + { + return ANY; + } + + new_signature = + new Merge() + { + @Override + protected Type lambda (final Type a, final Type b) + { + return (Type) a.generate_comparable_to(b); + } + }.merge(signature, e.signature); + + return new TextEffect(origin, new_signature, name); + } + + /**** Misc. ****************************************************************/ + @Override + public boolean is_incompatible_with_declaration (final DeclaredEntity de) + { + if (de instanceof TextEffect) + { + final TextEffect e; + + e = (TextEffect) de; + + if (signature.size() == e.signature.size()) + { + final List compatibility_result; + + /* + * Basically, the events are compatible if, and only if, the old + * signature is as least as restrictive as the new one. + */ + compatibility_result = + ( + new Merge() + { + @Override + protected Boolean lambda (final Type a, final Type b) + { + return + new Boolean(a.can_be_used_as(b)); + } + }.merge(signature, e.signature) + ); + + return compatibility_result.contains(Boolean.TRUE); + } + } + + return true; + } +} diff --git a/src/core/src/tonkadur/fate/v1/lang/World.java b/src/core/src/tonkadur/fate/v1/lang/World.java index 8419b06..edfb6fa 100644 --- a/src/core/src/tonkadur/fate/v1/lang/World.java +++ b/src/core/src/tonkadur/fate/v1/lang/World.java @@ -1,8 +1,8 @@ package tonkadur.fate.v1.lang; -import java.util.Collection; import java.util.HashSet; import java.util.List; +import java.util.Set; import tonkadur.parser.Context; import tonkadur.parser.Location; @@ -15,11 +15,12 @@ public class World /***************************************************************************/ /**** MEMBERS **************************************************************/ /***************************************************************************/ - protected final Collection loaded_files; + protected final Set loaded_files; + protected final Set required_extensions; protected final DeclarationCollection event_collection; // protected final DeclarationCollection macros; // protected final DeclarationCollection sequences; -// protected final DeclarationCollection text_effects; + protected final DeclarationCollection text_effect_collection; protected final DeclarationCollection type_collection; protected final DeclarationCollection variable_collection; @@ -31,12 +32,14 @@ public class World public World () { loaded_files = new HashSet(); + required_extensions = new HashSet(); event_collection = new DeclarationCollection(Event.value_on_missing()); //macros = new DeclarationCollection(); //sequences = new DeclarationCollection(); - //text_effects = new DeclarationCollection(); + text_effect_collection = + new DeclarationCollection(TextEffect.value_on_missing()); type_collection = new DeclarationCollection(Type.value_on_missing()); variable_collection = @@ -47,7 +50,7 @@ public class World /**** Accessors ************************************************************/ /**** Loaded Files ****/ - public Collection get_loaded_files () + public Set get_loaded_files () { return loaded_files; } @@ -62,16 +65,38 @@ public class World loaded_files.add(name); } - public DeclarationCollection types () + /**** Required Extensions ****/ + public Set get_required_extensions () { - return type_collection; + return required_extensions; + } + + public boolean requires_extension (final String name) + { + return required_extensions.contains(name); + } + + public void add_required_extension (final String name) + { + required_extensions.add(name); } + /**** Collections ****/ public DeclarationCollection events () { return event_collection; } + public DeclarationCollection text_effects () + { + return text_effect_collection; + } + + public DeclarationCollection types () + { + return type_collection; + } + public DeclarationCollection variables () { return variable_collection; @@ -96,6 +121,17 @@ public class World sb.append(System.lineSeparator()); } + sb.append(System.lineSeparator()); + sb.append("Required Extensions: "); + sb.append(System.lineSeparator()); + + for (final String filename: required_extensions) + { + sb.append("- "); + sb.append(filename); + sb.append(System.lineSeparator()); + } + sb.append(System.lineSeparator()); sb.append("Events: "); sb.append(System.lineSeparator()); @@ -103,6 +139,12 @@ public class World sb.append(System.lineSeparator()); sb.append(System.lineSeparator()); + sb.append("Text Effects: "); + sb.append(System.lineSeparator()); + sb.append(text_effect_collection.toString()); + sb.append(System.lineSeparator()); + sb.append(System.lineSeparator()); + sb.append("Types: "); sb.append(System.lineSeparator()); sb.append(type_collection.toString()); diff --git a/src/core/src/tonkadur/fate/v1/parser/FateParser.g4 b/src/core/src/tonkadur/fate/v1/parser/FateParser.g4 index 9d30b0f..2b581e7 100644 --- a/src/core/src/tonkadur/fate/v1/parser/FateParser.g4 +++ b/src/core/src/tonkadur/fate/v1/parser/FateParser.g4 @@ -71,10 +71,9 @@ first_level_fate_instr: */ } - | DECLARE_VARIABLE_KW scope=WORD WS+ type=WORD WS+ name=WORD R_PAREN + | DECLARE_VARIABLE_KW scope=WORD WS+ type WS+ name=WORD R_PAREN { final Origin start_origin, scope_origin, type_origin; - final Type variable_type; final Variable new_variable; VariableScope variable_scope; @@ -92,13 +91,6 @@ first_level_fate_instr: ($scope.getCharPositionInLine()) ); - type_origin = - CONTEXT.get_origin_at - ( - ($type.getLine()), - ($type.getCharPositionInLine()) - ); - variable_scope = VariableScope.value_of(($scope.text)); if (variable_scope == null) @@ -111,31 +103,44 @@ first_level_fate_instr: variable_scope = VariableScope.ANY; } - variable_type = WORLD.types().get(type_origin, ($type.text)); new_variable = new Variable ( start_origin, variable_scope, - variable_type, + ($type.result), ($name.text) ); WORLD.variables().add(new_variable); } - | DECLARE_TEXT_EFFECT_KW params=word_list name=WORD R_PAREN + | DECLARE_TEXT_EFFECT_KW params=type_list name=WORD R_PAREN { + final Origin start_origin; + final TextEffect new_text_effect; + + start_origin = + CONTEXT.get_origin_at + ( + ($DECLARE_TEXT_EFFECT_KW.getLine()), + ($DECLARE_TEXT_EFFECT_KW.getCharPositionInLine()) + ); + + new_text_effect = + new TextEffect(start_origin, ($type_list.result), ($name.text)); + + WORLD.text_effects().add(new_text_effect); } | REQUIRE_EXTENSION_KW name=WORD R_PAREN { + WORLD.add_required_extension(($name.text)); } - | DECLARE_ALIAS_TYPE_KW parent=WORD WS+ name=WORD R_PAREN + | DECLARE_ALIAS_TYPE_KW parent=type WS+ name=WORD R_PAREN { - final Origin start_origin, parent_origin; - final Type parent_type; + final Origin start_origin; final Type new_type; start_origin = @@ -145,15 +150,7 @@ first_level_fate_instr: ($DECLARE_ALIAS_TYPE_KW.getCharPositionInLine()) ); - parent_origin = - CONTEXT.get_origin_at - ( - ($parent.getLine()), - ($parent.getCharPositionInLine()) - ); - - parent_type = WORLD.types().get(parent_origin, ($parent.text)); - new_type = new Type(start_origin, parent_type, ($name.text)); + new_type = new Type(start_origin, ($parent.result), ($name.text)); WORLD.types().add(new_type); } @@ -174,8 +171,21 @@ first_level_fate_instr: { } - | DECLARE_EVENT_TYPE_KW name=WORD WS+ word_list R_PAREN + | DECLARE_EVENT_TYPE_KW name=WORD WS+ type_list R_PAREN { + final Origin start_origin; + final Event new_event; + + start_origin = + CONTEXT.get_origin_at + ( + ($DECLARE_EVENT_TYPE_KW.getLine()), + ($DECLARE_EVENT_TYPE_KW.getCharPositionInLine()) + ); + + new_event = new Event(start_origin, ($type_list.result), ($name.text)); + + WORLD.events().add(new_event); } | REQUIRE_KW WORD R_PAREN @@ -321,21 +331,57 @@ sentence } ; -word_list: - WORD? +type +returns [Type result] +: + WORD { + $result = + WORLD.types().get + ( + CONTEXT.get_origin_at + ( + ($WORD.getLine()), + ($WORD.getCharPositionInLine()) + ), + ($WORD.text) + ); } +; +catch [final Throwable e] +{ + throw new ParseCancellationException(e); +} - | WORD (WS+ WORD)* +type_list +returns [List result] +@init +{ + final List result = new ArrayList(); +} +: + ( + type + { + result.add(($type.result)); + } + )? + (WS+ + type + { + result.add(($type.result)); + } + )* { } ; typed_param_list: - (L_PAREN WORD WS+ WORD R_PAREN)* + (L_PAREN WORD WS+ type R_PAREN)* { } ; + /******************************************************************************/ /**** VALUES ******************************************************************/ /******************************************************************************/ -- cgit v1.2.3-70-g09d2