summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorNathanael Sensfelder <SpamShield0@MultiAgentSystems.org>2020-07-18 15:45:21 +0200
committerNathanael Sensfelder <SpamShield0@MultiAgentSystems.org>2020-07-18 15:45:21 +0200
commitbb22ba649662258368b86cbe7a0ef2b830f75c84 (patch)
treed424c5170bcbc958b184d026eb7f76f0e283ae08
parent69ede91538db84e620613b2ea3a4ae3536ee6f62 (diff)
Adds file path management.
-rw-r--r--data/examples/the_thief/include/chapters.fate2
-rw-r--r--data/examples/the_thief/include/characters.fate2
-rw-r--r--data/examples/the_thief/include/text_effects.fate3
-rw-r--r--data/examples/the_thief/include/type/character.fate4
-rw-r--r--src/core/src/tonkadur/Files.java55
-rw-r--r--src/core/src/tonkadur/Main.java4
-rw-r--r--src/core/src/tonkadur/RuntimeParameters.java14
-rw-r--r--src/core/src/tonkadur/fate/v1/Utils.java3
-rw-r--r--src/core/src/tonkadur/fate/v1/lang/Event.java2
-rw-r--r--src/core/src/tonkadur/fate/v1/lang/TextEffect.java2
-rw-r--r--src/core/src/tonkadur/fate/v1/lang/Variable.java2
-rw-r--r--src/core/src/tonkadur/fate/v1/lang/type/Type.java2
-rw-r--r--src/core/src/tonkadur/fate/v1/parser/FateLexer.g42
-rw-r--r--src/core/src/tonkadur/fate/v1/parser/FateParser.g441
-rw-r--r--src/core/src/tonkadur/parser/Context.java73
-rw-r--r--src/core/src/tonkadur/parser/Location.java14
-rw-r--r--src/core/src/tonkadur/parser/Origin.java7
17 files changed, 195 insertions, 37 deletions
diff --git a/data/examples/the_thief/include/chapters.fate b/data/examples/the_thief/include/chapters.fate
new file mode 100644
index 0000000..d7beb18
--- /dev/null
+++ b/data/examples/the_thief/include/chapters.fate
@@ -0,0 +1,2 @@
+(fate_version 1)
+
diff --git a/data/examples/the_thief/include/characters.fate b/data/examples/the_thief/include/characters.fate
index 4c36a8e..386d0de 100644
--- a/data/examples/the_thief/include/characters.fate
+++ b/data/examples/the_thief/include/characters.fate
@@ -1,6 +1,6 @@
(fate_version 1)
-(require include/type/character.fate)
+(require type/character.fate)
(declare_variable local character oscar)
(declare_variable local character carla)
diff --git a/data/examples/the_thief/include/text_effects.fate b/data/examples/the_thief/include/text_effects.fate
new file mode 100644
index 0000000..c8cdd7e
--- /dev/null
+++ b/data/examples/the_thief/include/text_effects.fate
@@ -0,0 +1,3 @@
+(fate_version 1)
+
+(declare_text_effect narrator)
diff --git a/data/examples/the_thief/include/type/character.fate b/data/examples/the_thief/include/type/character.fate
index e3b1b7b..5882fd5 100644
--- a/data/examples/the_thief/include/type/character.fate
+++ b/data/examples/the_thief/include/type/character.fate
@@ -1,7 +1,7 @@
(fate_version 1)
-(require include/type/stat.fate)
-(require include/type/location.fate)
+(require stat.fate)
+(require location.fate)
(declare_dict_type character
(string name)
diff --git a/src/core/src/tonkadur/Files.java b/src/core/src/tonkadur/Files.java
new file mode 100644
index 0000000..4673af4
--- /dev/null
+++ b/src/core/src/tonkadur/Files.java
@@ -0,0 +1,55 @@
+package tonkadur;
+
+import java.nio.file.Path;
+import java.nio.file.Paths;
+
+import tonkadur.parser.Context;
+
+public class Files
+{
+ /* Utility class. */
+ private Files () {}
+
+ public static String prepare_filename
+ (
+ final String filename
+ )
+ {
+ return Paths.get(filename).toAbsolutePath().normalize().toString();
+ }
+
+ public static String resolve_filename
+ (
+ final Context context,
+ final String name
+ )
+ {
+ Path candidate;
+
+ candidate = Paths.get(context.get_current_directory().toString(), name);
+
+ if (java.nio.file.Files.exists(candidate))
+ {
+ return candidate.toAbsolutePath().normalize().toString();
+ }
+
+ for (final String dir: RuntimeParameters.get_include_directories())
+ {
+ candidate = Paths.get(dir, name);
+
+ if (java.nio.file.Files.exists(candidate))
+ {
+ return candidate.toAbsolutePath().normalize().toString();
+ }
+ }
+
+ candidate = Paths.get(name);
+
+ if (java.nio.file.Files.exists(candidate))
+ {
+ return candidate.toAbsolutePath().normalize().toString();
+ }
+
+ return name;
+ }
+}
diff --git a/src/core/src/tonkadur/Main.java b/src/core/src/tonkadur/Main.java
index 382dab6..21bc077 100644
--- a/src/core/src/tonkadur/Main.java
+++ b/src/core/src/tonkadur/Main.java
@@ -20,9 +20,9 @@ public class Main
final Context context;
world = new World();
- context = new Context(args[0]);
+ context = Context.build(args[0]);
- Utils.add_file_content(args[0], context, world);
+ Utils.add_file_content(context.get_current_file(), context, world);
System.out.println("Parsing completed.");
System.out.println(world.toString());
diff --git a/src/core/src/tonkadur/RuntimeParameters.java b/src/core/src/tonkadur/RuntimeParameters.java
index 28a7416..2c434d2 100644
--- a/src/core/src/tonkadur/RuntimeParameters.java
+++ b/src/core/src/tonkadur/RuntimeParameters.java
@@ -1,18 +1,22 @@
package tonkadur;
+import java.util.ArrayList;
import java.util.Collection;
import java.util.HashSet;
+import java.util.List;
import tonkadur.error.ErrorCategory;
public class RuntimeParameters
{
+ protected static final List<String> include_directories;
protected static final Collection<ErrorCategory> disabled_errors;
protected static final Collection<ErrorCategory> tolerated_errors;
protected static boolean consider_warnings_as_errors;
static
{
+ include_directories = new ArrayList<String>();
disabled_errors = new HashSet<ErrorCategory>();
tolerated_errors = new HashSet<ErrorCategory>();
consider_warnings_as_errors = false;
@@ -32,4 +36,14 @@ public class RuntimeParameters
{
return consider_warnings_as_errors;
}
+
+ public static List<String> get_include_directories ()
+ {
+ return include_directories;
+ }
+
+ public static void add_include_directory (final String name)
+ {
+ include_directories.add(name);
+ }
}
diff --git a/src/core/src/tonkadur/fate/v1/Utils.java b/src/core/src/tonkadur/fate/v1/Utils.java
index 1049e0d..7cac057 100644
--- a/src/core/src/tonkadur/fate/v1/Utils.java
+++ b/src/core/src/tonkadur/fate/v1/Utils.java
@@ -39,7 +39,8 @@ public class Utils
if (parser.getNumberOfSyntaxErrors() > 0)
{
- throw new IOException("There were syntaxic errors in" + filename);
+ throw new IOException("There were syntaxic errors in " + filename);
}
}
+
}
diff --git a/src/core/src/tonkadur/fate/v1/lang/Event.java b/src/core/src/tonkadur/fate/v1/lang/Event.java
index 55b8c62..7b914b8 100644
--- a/src/core/src/tonkadur/fate/v1/lang/Event.java
+++ b/src/core/src/tonkadur/fate/v1/lang/Event.java
@@ -22,7 +22,7 @@ public class Event extends DeclaredEntity
ANY =
new Event
(
- new Origin(new Context(""), Location.BASE_LANGUAGE),
+ Origin.BASE_LANGUAGE,
new ArrayList<Type>(),
/*
* Use of a space necessary to avoid conflicting with a user created
diff --git a/src/core/src/tonkadur/fate/v1/lang/TextEffect.java b/src/core/src/tonkadur/fate/v1/lang/TextEffect.java
index dde0cfd..f833027 100644
--- a/src/core/src/tonkadur/fate/v1/lang/TextEffect.java
+++ b/src/core/src/tonkadur/fate/v1/lang/TextEffect.java
@@ -22,7 +22,7 @@ public class TextEffect extends Event
ANY =
new TextEffect
(
- new Origin(new Context(""), Location.BASE_LANGUAGE),
+ Origin.BASE_LANGUAGE,
new ArrayList<Type>(),
/*
* Use of a space necessary to avoid conflicting with a user created
diff --git a/src/core/src/tonkadur/fate/v1/lang/Variable.java b/src/core/src/tonkadur/fate/v1/lang/Variable.java
index 0b6bba5..dfd6c04 100644
--- a/src/core/src/tonkadur/fate/v1/lang/Variable.java
+++ b/src/core/src/tonkadur/fate/v1/lang/Variable.java
@@ -22,7 +22,7 @@ public class Variable extends DeclaredEntity
ANY =
new Variable
(
- new Origin(new Context(""), Location.BASE_LANGUAGE),
+ Origin.BASE_LANGUAGE,
VariableScope.ANY,
Type.ANY,
/*
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 4d3ad1d..87ef5fe 100644
--- a/src/core/src/tonkadur/fate/v1/lang/type/Type.java
+++ b/src/core/src/tonkadur/fate/v1/lang/type/Type.java
@@ -37,7 +37,7 @@ public class Type extends DeclaredEntity
{
final Origin base;
- base = new Origin(new Context(""), Location.BASE_LANGUAGE);
+ base = Origin.BASE_LANGUAGE;
/*
* Use of a space necessary to avoid conflicting with a user created type.
diff --git a/src/core/src/tonkadur/fate/v1/parser/FateLexer.g4 b/src/core/src/tonkadur/fate/v1/parser/FateLexer.g4
index f8fe10f..3654a30 100644
--- a/src/core/src/tonkadur/fate/v1/parser/FateLexer.g4
+++ b/src/core/src/tonkadur/fate/v1/parser/FateLexer.g4
@@ -31,7 +31,7 @@ DECLARE_VARIABLE_KW: L_PAREN 'declare_variable';
DEFINE_MACRO_KW: L_PAREN 'define_macro';
DEFINE_SEQUENCE_KW: L_PAREN 'define_sequence';
DIVIDE_KW: L_PAREN ('divide'|'/');
-ENABLE_TEXT_PARAMETER_KW: L_PAREN 'enable_text_parameter';
+ENABLE_TEXT_PARAMETER_KW: L_PAREN 'text_effect';
EQUALS_KW: L_PAREN ('equals'|'='|'==');
EVENT_KW: L_PAREN 'event';
EXTENSION_FIRST_LEVEL_KW: L_PAREN '@';
diff --git a/src/core/src/tonkadur/fate/v1/parser/FateParser.g4 b/src/core/src/tonkadur/fate/v1/parser/FateParser.g4
index bcda80d..4d111f5 100644
--- a/src/core/src/tonkadur/fate/v1/parser/FateParser.g4
+++ b/src/core/src/tonkadur/fate/v1/parser/FateParser.g4
@@ -13,6 +13,7 @@ options
import java.util.Map;
import java.util.HashMap;
+ import tonkadur.Files;
import tonkadur.error.ErrorManager;
@@ -77,7 +78,6 @@ returns [List<InstructionNode> result]
}
WS*)*
{
- /* TODO */
}
;
@@ -371,20 +371,23 @@ first_level_fate_instr:
| REQUIRE_KW WS+ WORD WS* R_PAREN
{
- if (!WORLD.has_loaded_file(($WORD.text)))
+ final String filename;
+
+ filename = Files.resolve_filename(CONTEXT, ($WORD.text));
+
+ if (!WORLD.has_loaded_file(filename))
{
CONTEXT.push
(
- new Location
+ CONTEXT.get_location_at
(
- CONTEXT.get_current_file(),
($REQUIRE_KW.getLine()),
($REQUIRE_KW.getCharPositionInLine())
),
- ($WORD.text)
+ filename
);
- Utils.add_file_content(($WORD.text), CONTEXT, WORLD);
+ Utils.add_file_content(filename, CONTEXT, WORLD);
CONTEXT.pop();
}
@@ -392,18 +395,21 @@ first_level_fate_instr:
| INCLUDE_KW WS+ WORD WS* R_PAREN
{
+ final String filename;
+
+ filename = Files.resolve_filename(CONTEXT, ($WORD.text));
+
CONTEXT.push
(
- new Location
+ CONTEXT.get_location_at
(
- CONTEXT.get_current_file(),
($INCLUDE_KW.getLine()),
($INCLUDE_KW.getCharPositionInLine())
),
- ($WORD.text)
+ filename
);
- Utils.add_file_content(($WORD.text), CONTEXT, WORLD);
+ Utils.add_file_content(filename, CONTEXT, WORLD);
CONTEXT.pop();
}
@@ -440,8 +446,6 @@ returns [InstructionNode result]
:
L_PAREN WS+ general_fate_sequence WS* R_PAREN
{
- /* TODO */
-
$result =
new InstructionList
(
@@ -1043,8 +1047,17 @@ returns [ValueNode result]:
| IS_MEMBER_KW WS+ value WS+ value_reference WS* R_PAREN
{
- /* TODO */
- $result = null;
+ $result =
+ IsMemberOperator.build
+ (
+ CONTEXT.get_origin_at
+ (
+ ($IS_MEMBER_KW.getLine()),
+ ($IS_MEMBER_KW.getCharPositionInLine())
+ ),
+ ($value.result),
+ ($value_reference.result)
+ );
}
;
catch [final Throwable e]
diff --git a/src/core/src/tonkadur/parser/Context.java b/src/core/src/tonkadur/parser/Context.java
index c3278ff..edb1e68 100644
--- a/src/core/src/tonkadur/parser/Context.java
+++ b/src/core/src/tonkadur/parser/Context.java
@@ -1,41 +1,64 @@
package tonkadur.parser;
+import java.nio.file.Path;
+import java.nio.file.Paths;
+
+import java.io.IOException;
+
import java.util.Stack;
public class Context
{
+ public static Context BASE_LANGUAGE;
+
+ static
+ {
+ BASE_LANGUAGE = new Context(null, "<Base Language>");
+ }
+
/***************************************************************************/
/**** MEMBERS **************************************************************/
/***************************************************************************/
protected final Stack<Location> source;
+ protected Path current_directory;
protected String current_file;
/***************************************************************************/
/**** PUBLIC ***************************************************************/
/***************************************************************************/
-
/**** Constructors *********************************************************/
- public Context (final String filename)
+ public static Context build (String filename)
{
- source = new Stack<Location>();
- current_file = filename;
+ Path current_directory;
+
+ current_directory = Paths.get(filename).toAbsolutePath().normalize();
+ filename = current_directory.toString();
+ current_directory = current_directory.getParent();
+
+ return new Context(current_directory, filename);
}
/**** Accessors ************************************************************/
public void push (final Location location, final String new_file)
- throws ContextCycleException
+ throws
+ ContextCycleException
{
throw_exception_on_cycle(location, new_file);
current_file = new_file;
+ current_directory = Paths.get(new_file).getParent();
source.push(location);
}
public void pop ()
{
- current_file = source.peek().get_filename();
- source.pop();
+ final Location previous_location;
+
+ previous_location = source.pop();
+
+ current_file = previous_location.get_filename();
+ current_directory = previous_location.get_directory();
}
public String get_current_file ()
@@ -43,10 +66,31 @@ public class Context
return current_file;
}
+ public Path get_current_directory ()
+ {
+ return current_directory;
+ }
+
/**** Utils ****************************************************************/
public Origin get_origin_at (final int line, final int column)
{
- return new Origin(clone(), new Location(current_file, line, column));
+ return
+ new Origin
+ (
+ clone(),
+ new Location
+ (
+ current_directory,
+ current_file,
+ line,
+ column
+ )
+ );
+ }
+
+ public Location get_location_at (final int line, final int column)
+ {
+ return new Location(current_directory, current_file, line, column);
}
public Origin get_origin_at (final Location location)
@@ -105,7 +149,7 @@ public class Context
{
final Context result;
- result = new Context("");
+ result = new Context(current_directory, current_file);
/*
* That's in FIFO order, as we want it to be, due to arguable design
@@ -116,14 +160,21 @@ public class Context
result.source.push(location);
}
- result.current_file = current_file;
-
return result;
}
/***************************************************************************/
/**** PROTECTED ************************************************************/
/***************************************************************************/
+ /**** Constructors *********************************************************/
+ protected Context (final Path directory, final String filename)
+ {
+ source = new Stack<Location>();
+ current_file = filename;
+ current_directory = directory;
+ }
+
+ /**** Utils ****************************************************************/
protected void throw_exception_on_cycle
(
final Location declared_at,
diff --git a/src/core/src/tonkadur/parser/Location.java b/src/core/src/tonkadur/parser/Location.java
index ea6989b..8e86a95 100644
--- a/src/core/src/tonkadur/parser/Location.java
+++ b/src/core/src/tonkadur/parser/Location.java
@@ -1,5 +1,7 @@
package tonkadur.parser;
+import java.nio.file.Path;
+
public class Location
{
/***************************************************************************/
@@ -9,7 +11,7 @@ public class Location
static
{
- BASE_LANGUAGE = new Location(true, "", -1, -1);
+ BASE_LANGUAGE = new Location(true, null, "", -1, -1);
}
/***************************************************************************/
@@ -17,6 +19,7 @@ public class Location
/***************************************************************************/
protected final boolean is_base_language;
protected final String filename;
+ protected final Path directory;
protected final int line;
protected final int column;
@@ -26,12 +29,14 @@ public class Location
protected Location
(
final boolean is_base_language,
+ final Path directory,
final String filename,
final int line,
final int column
)
{
this.is_base_language = is_base_language;
+ this.directory = directory;
this.filename = filename;
this.line = line;
this.column = column;
@@ -44,18 +49,25 @@ public class Location
/**** Constructors *********************************************************/
public Location
(
+ final Path directory,
final String filename,
final int line,
final int column
)
{
this.is_base_language = false;
+ this.directory = directory;
this.filename = filename;
this.line = line;
this.column = column;
}
/**** Accessors ************************************************************/
+ public Path get_directory ()
+ {
+ return directory;
+ }
+
public String get_filename ()
{
return filename;
diff --git a/src/core/src/tonkadur/parser/Origin.java b/src/core/src/tonkadur/parser/Origin.java
index f6f2d29..9d41fac 100644
--- a/src/core/src/tonkadur/parser/Origin.java
+++ b/src/core/src/tonkadur/parser/Origin.java
@@ -2,6 +2,13 @@ package tonkadur.parser;
public class Origin
{
+ public static final Origin BASE_LANGUAGE;
+
+ static
+ {
+ BASE_LANGUAGE = new Origin(Context.BASE_LANGUAGE, Location.BASE_LANGUAGE);
+ }
+
/***************************************************************************/
/**** MEMBERS **************************************************************/
/***************************************************************************/