diff --git a/.idea/artifacts/quailTestAddon.xml b/.idea/artifacts/quailTestAddon.xml
new file mode 100644
index 0000000..3d36db4
--- /dev/null
+++ b/.idea/artifacts/quailTestAddon.xml
@@ -0,0 +1,8 @@
+
+
See:
");
+ for (String see : seeLinks)
+ sb.append("")
+ .append(convertSeeLink(see))
+ .append("");
+ sb.append("
Author: ").append(authors.get(0)).append("
"); } diff --git a/QuailRuntimeEnvironment/src/main/java/me/tapeline/quailj/io/IO.java b/QuailRuntimeEnvironment/src/main/java/me/tapeline/quailj/io/IO.java index 3f364bc..da62a6d 100644 --- a/QuailRuntimeEnvironment/src/main/java/me/tapeline/quailj/io/IO.java +++ b/QuailRuntimeEnvironment/src/main/java/me/tapeline/quailj/io/IO.java @@ -11,8 +11,6 @@ */ public interface IO { - // TODO: rebase all new File() onto IO::file() - /** * Sets the current encoding * @param encoding new encoding diff --git a/QuailRuntimeEnvironment/src/main/java/me/tapeline/quailj/launcher/LaunchCommandParser.java b/QuailRuntimeEnvironment/src/main/java/me/tapeline/quailj/launcher/LaunchCommandParser.java index 1c0f64d..366e580 100644 --- a/QuailRuntimeEnvironment/src/main/java/me/tapeline/quailj/launcher/LaunchCommandParser.java +++ b/QuailRuntimeEnvironment/src/main/java/me/tapeline/quailj/launcher/LaunchCommandParser.java @@ -70,9 +70,15 @@ private void parseFlag(String flag) { else { String flagName = flag.substring(3, flag.indexOf('=')); if (flagName.equals("encoding")) - globalFlags.put("encoding", flag.substring(flag.indexOf('=' + 1))); + globalFlags.put("encoding", flag.substring(flag.indexOf('=') + 1)); if (flagName.equals("ignoreDocs")) - globalFlags.put("ignoreDocs", toBoolean(flag.substring(flag.indexOf('=' + 1)))); + globalFlags.put("ignoreDocs", toBoolean(flag.substring(flag.indexOf('=') + 1))); + if (flagName.equals("debugPort")) + globalFlags.put("debugPort", Short.parseShort(flag.substring(flag.indexOf('=') + 1))); + if (flagName.equals("displayReturnValue")) + globalFlags.put("displayReturnValue", toBoolean(flag.substring(flag.indexOf('=') + 1))); + if (flagName.equals("addons")) + globalFlags.put("addons", flag.substring(flag.indexOf('=') + 1)); } } else { int assignPosition = 0; diff --git a/QuailRuntimeEnvironment/src/main/java/me/tapeline/quailj/launcher/QuailLauncher.java b/QuailRuntimeEnvironment/src/main/java/me/tapeline/quailj/launcher/QuailLauncher.java index 46aee9e..2973714 100644 --- a/QuailRuntimeEnvironment/src/main/java/me/tapeline/quailj/launcher/QuailLauncher.java +++ b/QuailRuntimeEnvironment/src/main/java/me/tapeline/quailj/launcher/QuailLauncher.java @@ -1,6 +1,7 @@ package me.tapeline.quailj.launcher; import me.tapeline.quailj.GlobalFlags; +import me.tapeline.quailj.addons.*; import me.tapeline.quailj.debugging.DebugServer; import me.tapeline.quailj.docgen.DocumentationGenerator; import me.tapeline.quailj.io.DefaultIO; @@ -20,8 +21,11 @@ import java.io.File; import java.io.IOException; +import java.util.Arrays; import java.util.HashMap; import java.util.List; +import java.util.function.Predicate; +import java.util.stream.Collectors; public class QuailLauncher { // TODO: refactor @@ -49,6 +53,8 @@ private void setupGlobalFlags(HashMap
+An easy-to-use scripting language with simple yet powerful syntax
+
+
+![GitHub License](https://img.shields.io/github/license/Quail-Language/quail)
+![GitHub Downloads (all assets, all releases)](https://img.shields.io/github/downloads/Quail-Language/quail/total)
+![GitHub Actions Workflow Status](https://img.shields.io/github/actions/workflow/status/Quail-Language/quail/main.yml)
+![GitHub Issues or Pull Requests](https://img.shields.io/github/issues/Quail-Language/quail)
+![GitHub Release](https://img.shields.io/github/v/release/Quail-Language/quail)
+
+Website
+·
+Docs
+·
+Issues
+
+ @echo off + if exist "%QUAIL_HOME%\jre\jdk1.8.0_402\bin\java.exe" ( + "%QUAIL_HOME%\jre\jdk1.8.0_402\bin\java.exe" -jar "%QUAIL_HOME%\qdk.jar" %* + ) + if not exist "%QUAIL_HOME%\jre\jdk1.8.0_402\bin\java.exe" ( + java -jar "%QUAIL_HOME%\qdk.jar" %* + ) + ``` +6. Now you can access Quail with `quail` and `quail-qdk` commands + +##### On Linux +1. Make sure you have at least Java 8 installed +2. Download your chosen Quail version +3. Place `qre.jar` and/or `qdk.jar` into `/bin/quail-jars/` +4. Place the following contents into file at `/bin/quail` + ``` + #!/bin/bash + java -jar /bin/quail-jars/qre.jar $@ + ``` +5. Place the following contents into file at `/bin/quail-qdk` + ``` + #!/bin/bash + java -jar /bin/quail-jars/qdk.jar $@ + ``` +6. Run + ``` + sudo chmod +x /bin/quail + sudo chmod +x /bin/quail-qdk + ``` +7. Now you can access Quail with `quail` and `quail-qdk` commands + +### First test +Write a short script: +```lua +print("Hello, World!") +``` + +Then execute it: +``` +quail run myscript.q +``` + +You will see the output in your console + +### Where to go next? + +If you are completely new or an amateur to programming, read +[Getting Started with Quail 2.0+](https://github.com/Quail-Language/quail/wiki/Getting-Started-with-Quail-v2.0) + +If you are very confident with different languages, and you are aware +of abstract syntax concepts, you can go straight to +[Quail Specification](https://quail-language.github.io/docs/spec/), +[Quail Core Docs](https://quail-language.github.io/docs/core/) and +[Quail Library Docs](https://quail-language.github.io/docs/libs/) + +### License + +This work is licensed under GNU General Public License v3.0 + +### Contact + +You can contact the developer in the +[Issues](https://github.com/Quail-Language/quail/issues) tab or in +[Discord server](https://discord.gg/8smQAa8whM). ### Developer -Project was being built from scratch and is being developed now only by [@Tapeline](https://www.github.com/Tapeline) +Project was being built from scratch and is being developed now +only by [@Tapeline](https://www.github.com/Tapeline) diff --git a/docs-md/dev-tutorials/1-how-to-create-addon.md b/docs-md/dev-tutorials/1-how-to-create-addon.md new file mode 100644 index 0000000..85dc471 --- /dev/null +++ b/docs-md/dev-tutorials/1-how-to-create-addon.md @@ -0,0 +1,101 @@ +# Quail Developer Tutorials + +## How to create an addon + +### Step 1. Create a project +First of all, create a **Java 8** project. Add QRE (`qre.jar`) as a dependency. + +Also make sure, that when you compile your project into a .jar, it compiles +**without dependencies**. + +### Step 2. Create an addon class +Create a class that extends from `me.tapeline.quailj.addons.QuailAddon` + +You are going to need to implement methods. For example: + +```java +package me.tapeline.quail.addons; + +import me.tapeline.quailj.addons.QuailAddon; +import me.tapeline.quailj.parsing.annotation.Annotation; +import me.tapeline.quailj.preprocessing.directives.AbstractDirective; +import me.tapeline.quailj.runtime.librarymanagement.BuiltinLibrary; + +import java.util.Arrays; +import java.util.List; + +public class QuailTestAddon extends QuailAddon { + + @Override + public String getName() { + return "QuailTestAddon"; + } + + @Override + public ListprovidedDirectives() { + return Arrays.asList( + new MyTestDirective() + ); + } + + @Override + public List providedAnnotations() { + return Arrays.asList( + new MyTestAnnotation() + ); + } + + @Override + public List providedLibraries() { + return Arrays.asList( + new MyTestLibrary() + ); + } + +} +``` + +Here, `getName` method should return the name of your addon, other 3 methods +should return a list of things addon provides. + +Notice: return values of them +under any circumstances should not be `null`. If you don't provide, for example, +any directives, just return an empty list: + +```java +public List providedDirectives() { + return new ArrayList<>(); +} +``` + +### Step 3. Define main class for addon +Now head to your project resources and create a file called `addonMainClass` +without any extension. + +You should place a fully qualified ID of your newly created QuailAddon class +in there. + +Notice: this file should end with `\n`. + +Example: +``` +me.tapeline.quail.addons.QuailTestAddon + +``` + +### Step 4. Create some content for your addon + +Now you can create directives, annotations, libraries, etc. for your +addon, just don't forget to register them in your main class. + +### Step 5. Packaging + +Package your addon into a .jar. + +**Remember to include `addonMainClass` resource and exclude dependencies!** + +### Step 6. Using addon + +To attach an addon use global flag `-G.addons` + +More info on this topic in Quail Specification Chapter 16. diff --git a/docs-md/dev-tutorials/2-how-to-create-directives.md b/docs-md/dev-tutorials/2-how-to-create-directives.md new file mode 100644 index 0000000..9753139 --- /dev/null +++ b/docs-md/dev-tutorials/2-how-to-create-directives.md @@ -0,0 +1,37 @@ +# Quail Developer Tutorials + +## How to create a preprocessor directive + +To create a preprocessor directive you need to create a class that extends +from `me.tapeline.quailj.preprocessing.directives.AbstractDirective`: + +```java +public class MyTestDirective extends AbstractDirective { + + @Override + public String prefix() { + return "testdirective"; + } + + @Override + public List arguments() { + return new ArrayList<>(); + } + + @Override + public String applyDirective(String code, File scriptHome, StringBoundariesMap boundaries, Object... arguments) { + System.out.println("Test directive applied"); + return code; + } + +} +``` + +Implement methods: +- `prefix` should return name of the directive. Prefix="testdirective" will + correspond to this syntax: `#:testdirective` +- `arguments` should return a list of directive arguments. More info about + this can be found in Quail Specification Chapter 3 +- `applyDirective` should return the source code after applying this directive + with given `arguments`, minding the fact that content in strings generally + should not be touched. Locations of strings are given in `boundaries` \ No newline at end of file diff --git a/docs-md/dev-tutorials/3-how-to-create-annotations.md b/docs-md/dev-tutorials/3-how-to-create-annotations.md new file mode 100644 index 0000000..005edfe --- /dev/null +++ b/docs-md/dev-tutorials/3-how-to-create-annotations.md @@ -0,0 +1,28 @@ +# Quail Developer Tutorials + +## How to create a parser annotation + +To create a parser annotation you need to create a class that implements +`me.tapeline.quailj.parsing.annotation.Annotation`: + +```java +public class MyTestAnnotation implements Annotation { + @Override + public String name() { + return "MyTestAnnotation"; + } + + @Override + public Node apply(Node target, Object... args) { + System.out.println("MyTestAnnotation called with args:"); + System.out.println(Arrays.toString(args)); + return target; + } +} +``` + +Implement methods: +- `name` should return name of the annotation. Name="MyTestAnnotation" will + correspond to this syntax: `@MyTestAnnotation` +- `apply` should return the AST node after applying this annotation + with given `args` diff --git a/docs-md/dev-tutorials/index.md b/docs-md/dev-tutorials/index.md new file mode 100644 index 0000000..a8546e7 --- /dev/null +++ b/docs-md/dev-tutorials/index.md @@ -0,0 +1,9 @@ +# Quail Developer Tutorials + +This section contains tutorials about developing for Quail in Java + +[How to create a Quail Addon](1-how-to-create-addon.md) + +[How to create a preprocessor directive](2-how-to-create-directives.md) + +[How to create a parser annotation](3-how-to-create-annotations.md) \ No newline at end of file diff --git a/docs-md/index.md b/docs-md/index.md new file mode 100644 index 0000000..347d945 --- /dev/null +++ b/docs-md/index.md @@ -0,0 +1,11 @@ +## Quail Documentation Home + +[Back to home](/) + +[Quail Specification](spec/) + +[Quail Core Docs](core/) + +[Quail Library Docs](libs/) + +[Quail Developer Tutorials](dev-tutorials/) diff --git a/docs-md/libs/data.html b/docs-md/libs/data.html new file mode 100644 index 0000000..96d5f0d --- /dev/null +++ b/docs-md/libs/data.html @@ -0,0 +1,68 @@ + + + + + + + + + + Docs + + ++ \ No newline at end of file diff --git a/docs-md/libs/data.q b/docs-md/libs/data.q new file mode 100644 index 0000000..bafe6ac --- /dev/null +++ b/docs-md/libs/data.q @@ -0,0 +1,108 @@ +#?toc-entry Queue +#?toc-entry Deque +#?toc-entry Set +#?toc-entry Bytes + +#?htmlThis library some useful data structures
+
lang/data
++
Queue
Implementation of a single-ended queue.
Supportsin
operator and iterationFields
None
Methods
void add(this, object obj)
Add object to back of queue
void clear(this)
object peek(this)
Get object from front without popping it.
If queue is empty, null is returned
object pop(this)
Pop object from front.
If queue is empty, null is returned
num size(this)
+
Deque
Implementation of a double-ended queue.
Supportsin
operator and iterationFields
None
Methods
void addBack(this, object obj)
Add object to back of queue
void addFront(this, object obj)
Add object to front of queue
void clear(this)
object peekBack(this)
Get object from front without popping it.
If queue is empty, null is returned
object peekFront(this)
Get object from front without popping it.
If queue is empty, null is returned
object popBack(this)
Pop object from back.
If queue is empty, null is returned
object popFront(this)
Pop object from front.
If queue is empty, null is returned
num size(this)
+
Set
Implementation of a set.
Can contain only booleans, strings and numbers
Supportsin
operator, equality check and iterationFields
None
Methods
_constructor(this, list | void values)
Constructs an empty set and adds all values (if specified)
void add(this, bool | string | num obj)
Add object to set. If object is already in set - nothing happens
void clear(this)
object static intersection(a, b)
StaticIntersection of 2 sets
void remove(this, bool | string | num obj)
Remove object from set. If object is not in set - nothing happens
num size(this)
object static union(a, b)
StaticUnion of 2 sets
+
Bytes
Implementation of a byte array.
Supports equality check, iteration, indexing and subscriptsFields
None
Methods
object static and(string | object a, string | object b)
Static
string static asBase64(string | object bytes)
Static
num static asBits(string | object bytes)
Static
num static asSignedInt(string | object bytes)
Static
num static asUnsignedInt(string | object bytes)
Static
bool bitAt(this, num pos)
object static fromBase64(string b64)
Static
object static fromBits(string bits)
Static
object static fromSignedInt(num uint)
Static
object static implies(string | object a, string | object b)
Static
object static nand(string | object a, string | object b)
Static
object static nor(string | object a, string | object b)
Static
object static or(string | object a, string | object b)
Static
void setBitAt(this, num pos, bool bit)
object static xnor(string | object a, string | object b)
Static
object static xor(string | object a, string | object b)
Static+#?html
lang/data
+#? This library some useful data structures + +class Queue { + #? Implementation of a single-ended queue. + #? Supportsin
operator and iteration + + num size(this) {} + void add(this, object obj) { + #? Add object to back of queue + } + object pop(this) { + #? Pop object from front. + #? If queue is empty, null is returned + } + void clear(this) {} + object peek(this) { + #? Get object from front without popping it. + #? If queue is empty, null is returned + } +} + +class Deque { + #? Implementation of a double-ended queue. + #? Supportsin
operator and iteration + + num size(this) {} + void addFront(this, object obj) { + #? Add object to front of queue + } + void addBack(this, object obj) { + #? Add object to back of queue + } + object popFront(this) { + #? Pop object from front. + #? If queue is empty, null is returned + } + object popBack(this) { + #? Pop object from back. + #? If queue is empty, null is returned + } + void clear(this) {} + object peekFront(this) { + #? Get object from front without popping it. + #? If queue is empty, null is returned + } + object peekBack(this) { + #? Get object from front without popping it. + #? If queue is empty, null is returned + } +} + +class Set { + #? Implementation of a set. + #? Can contain only booleans, strings and numbers + #? Supportsin
operator, equality check and iteration + + constructor (this, list | void values=null) { + #? Constructs an empty set and adds all values (if specified) + } + + num size(this) {} + void add(this, bool | string | num obj) { + #? Add object to set. If object is already in set - nothing happens + } + void remove(this, bool | string | num obj) { + #? Remove object from set. If object is not in set - nothing happens + } + void clear(this) {} + + static object union(a, b) { + #? Union of 2 sets + } + static object intersection(a, b) { + #? Intersection of 2 sets + } +} + +class Bytes { + #? Implementation of a byte array. + #? Supports equality check, iteration, indexing and subscripts + + static object fromBase64(string b64) {} + static object fromBits(string bits) {} + static object fromSignedInt(num uint) {} + static string asBase64(string|object bytes) {} + static num asUnsignedInt(string|object bytes) {} + static num asSignedInt(string|object bytes) {} + static num asBits(string|object bytes) {} + + static object or(string|object a, string|object b) {} + static object and(string|object a, string|object b) {} + static object xor(string|object a, string|object b) {} + static object implies(string|object a, string|object b) {} + static object nor(string|object a, string|object b) {} + static object nand(string|object a, string|object b) {} + static object xnor(string|object a, string|object b) {} + + bool bitAt(this, num pos) {} + void setBitAt(this, num pos, bool bit) {} +} + diff --git a/docs-md/libs/index.md b/docs-md/libs/index.md index 8d26c87..a8df0d2 100644 --- a/docs-md/libs/index.md +++ b/docs-md/libs/index.md @@ -16,4 +16,8 @@ [`lang/reflect`](reflect) -[`lang/storage`](storage) \ No newline at end of file +[`lang/storage`](storage) + +[`lang/data`](data) + +[`lang/time`](time) diff --git a/docs-md/libs/ji.html b/docs-md/libs/ji.html index 171a07f..4466aa1 100644 --- a/docs-md/libs/ji.html +++ b/docs-md/libs/ji.html @@ -82,13 +82,13 @@ji.q
lang/ji
-
JavaClass
Proxy for Java classes
Fields
static CLASS
static ABSTRACT
static INTERFACE
Methods
_constructor(this, args...)
Instantiate JavaObject of that class
+
JavaMethod
Proxy for Java classes
Fields
static CLASS
static ABSTRACT
static INTERFACE
Methods
_constructor(this, args...)
Instantiate JavaObject of that class
See:
#JavaObject
JavaMethod
Proxy for Java methods
Fields
None
Methods
None
-
JavaObject
Proxy for Java objects
Fields
None
Methods
object getClass(this)
Get class (instance of JavaClass)
object static pack(object obj)
StaticWraps Quail native value as a JavaObject
-
SketchedJavaClass
Used for runtime creation of Java classes
Fields
None
Methods
_constructor(this, string signature, contents...)
Prepares a Java class.
Signature is a sequence of Java keyword modifiers and name of the class:
E.g.public final ClassName
Contents is a sequence of SketchedJavaConstructors, SketchedJavaFields,
SketchedJavaInheritances and SketchedJavaMethods+
SketchedJavaConstructor
Proxy for Java objects
Fields
None
Methods
object getClass(this)
Get class (instance of JavaClass)
See:
#JavaClass
object static pack(object obj)
StaticWraps Quail native value as a JavaObject
+
SketchedJavaClass
Used for runtime creation of Java classes
Fields
None
Methods
_constructor(this, string signature, contents...)
Prepares a Java class.
Signature is a sequence of Java keyword modifiers and name of the class:
E.g.public final ClassName
Contents is a sequence of SketchedJavaConstructors, SketchedJavaFields,
SketchedJavaInheritances and SketchedJavaMethodsSee:
#SketchedJavaField#SketchedJavaInheritance#SketchedJavaMethod#SketchedJavaConstructor
SketchedJavaConstructor
Used for runtime creation of Java class constructors
Fields
None
Methods
_constructor(this, string signature, list args, func body)
Prepares a Java class constructor.
Signature is a sequence of Java keyword modifiers: public, private, protected, static, final
E.g.public
Args is a list of strings that contain argument signatures.
E.g.["double a", "String b"]
Body is the Quail function that will be executed when this constructor is invoked
SketchedJavaField
Used for runtime creation of Java class fields
Fields
None
Methods
_constructor(this, string signature, object default)
Prepares a Java class sequence.
Signature is a sequence of Java keyword modifiers (public, private, protected, static, final),
a type (double, String, boolean...) and a name. E.g. public double a
Default is an instance of JavaObject. Resembles the default value of this field-
SketchedJavaInheritance
Used for inheritance of runtime created Java classes
Fields
None
Methods
_constructor(this, object extends)
Receives a JavaClass instance of extension or implementation
+
SketchedJavaMethod
Used for inheritance of runtime created Java classes
Fields
None
Methods
_constructor(this, object extends)
Receives a JavaClass instance of extension or implementation
See:
#JavaClass
SketchedJavaMethod
Used for runtime creation of Java class methods
Fields
None
Methods
_constructor(this, string signature, list args, func body)
Prepares a Java class constructor.
Signature is a sequence of Java keyword modifiers (public, private, protected, static, final),
a type (double, String, boolean...) and a name. E.g. public double a
Args is a list of strings that contain argument signatures.
E.g.["double a", "String b"]
Body is the Quail function that will be executed when this method is invoked-
SketchedJavaPackage
Used for runtime creation of Java packages
Fields
None
Methods
_constructor(this, string name, classes...)
Classes is a sequence of SketchedJavaClasses
getClass(string className)
Get defined Java class by qualified ID
deployPackage(object package)
Creates all Java classes specified in passed SketchedJavaPackage