mirror of
https://github.com/Kugelschieber/asl.git
synced 2026-01-18 12:00:25 +00:00
Added main.
This commit is contained in:
25
README.md
25
README.md
@@ -1,7 +1,5 @@
|
||||
# ASL
|
||||
|
||||
**ASL is under heavy development and not production ready, the features listed here are not fully implemented. Please visit again when the final version is releaesed. If you like to contribute or if you are just interested, go on.**
|
||||
|
||||
ASL stands for Arma Scripting Language, a C-style scripting language compiled to SQF.
|
||||
ASL is intended to simplify Arma 3 mod and mission development and eliminate the pain of SQF's bad syntax.
|
||||
|
||||
@@ -16,6 +14,29 @@ Main reasons for ASL:
|
||||
|
||||
The compiler is written in Go and implemented as a simple recursive decent parser and uses concurrency to compile multiple files at once, which makes it really fast.
|
||||
|
||||
## Usage
|
||||
|
||||
ASL is a command line tool. After you have downloaded it, execute it using the terminal/"cmd" by navigating to the binary or setting PATH variable and executing the following statement:
|
||||
|
||||
```
|
||||
asl [-v|-r|-pretty|--help] <input directory> <output directory>
|
||||
```
|
||||
|
||||
| Parameter | Optional/Required | Meaning |
|
||||
| --------- | ----------------- | ------- |
|
||||
| -v | optional | Shows ASL version. |
|
||||
| -r | optional | Read input directory recursively. |
|
||||
| -pretty | optional | Enable pretty printing to SQF. |
|
||||
| --help | optional | Show usage. |
|
||||
| <input directory> | required | Directory to read ASL files from. |
|
||||
| <output directory> | required | Directory for SQF output. Can be the same as input directory. |
|
||||
|
||||
**Example:**
|
||||
|
||||
```
|
||||
asl ./missions/myMission/myScripts ./missions/myMission/compiledScripts
|
||||
```
|
||||
|
||||
## Syntax
|
||||
|
||||
### Comments
|
||||
|
||||
2
ToDo.md
2
ToDo.md
@@ -5,7 +5,7 @@
|
||||
* ~~solution for build in commands which do not require left values~~
|
||||
* ~~pretty/minified printing~~
|
||||
* ~~usage~~
|
||||
* recursive compiling
|
||||
* ~~recursive compiling~~
|
||||
* concurrent compiling
|
||||
* ~~inline buildin function call -> foo(a)(bar(x)(y));~~
|
||||
* ~~negative values e.g. -1, operator !~~
|
||||
|
||||
@@ -22,13 +22,13 @@ if (!isNil _getunit) then { // unit exists?
|
||||
*/
|
||||
|
||||
if !isServer && player != player {
|
||||
exit()(); // does not work for SQF, need to implement exitWith...
|
||||
waituntil(player == player);
|
||||
}
|
||||
|
||||
var _getunit = select(_this)(0);
|
||||
var _file = select(_this)(1);
|
||||
|
||||
if !(isNil()(_getunit)) {
|
||||
if !isNil()(_getunit) {
|
||||
var _unit = objNull;
|
||||
call()(compile()(format()("_unit = %1", _getunit)));
|
||||
|
||||
|
||||
8
in/sub/sub.asl
Normal file
8
in/sub/sub.asl
Normal file
@@ -0,0 +1,8 @@
|
||||
var x = 1;
|
||||
var y = 3;
|
||||
|
||||
func foo(x, y) {
|
||||
return x+y
|
||||
}
|
||||
|
||||
hint()(format()("%1", foo(x, y)));
|
||||
0
in/sub/test.txt
Normal file
0
in/sub/test.txt
Normal file
15
out/complex.sqf
Normal file
15
out/complex.sqf
Normal file
@@ -0,0 +1,15 @@
|
||||
if (!isServer&&player!=player) then {
|
||||
waitUntil {player==player};
|
||||
};
|
||||
_getunit = (_this select 0);
|
||||
_file = (_this select 1);
|
||||
if (!(isNil _getunit)) then {
|
||||
_unit = objNull;
|
||||
call (compile (format ["_unit = %1", _getunit]));
|
||||
if ((local _unit)) then {
|
||||
try {
|
||||
_unit execVM _file;
|
||||
} catch {
|
||||
};
|
||||
};
|
||||
};
|
||||
7
out/simple.sqf
Normal file
7
out/simple.sqf
Normal file
@@ -0,0 +1,7 @@
|
||||
waitUntil {x=x+1;x<100};
|
||||
if (timeIsOver) then {
|
||||
if (true) exitWith {
|
||||
[] call foo;
|
||||
[] call bar;
|
||||
};
|
||||
};
|
||||
8
out/sub/sub.sqf
Normal file
8
out/sub/sub.sqf
Normal file
@@ -0,0 +1,8 @@
|
||||
x = 1;
|
||||
y = 3;
|
||||
foo = {
|
||||
x = _this select 0;
|
||||
y = _this select 1;
|
||||
return x+y;
|
||||
};
|
||||
hint (format ["%1", ([x, y] call foo)]);
|
||||
134
src/main/asl.go
134
src/main/asl.go
@@ -4,24 +4,140 @@ import (
|
||||
"asl"
|
||||
"fmt"
|
||||
"io/ioutil"
|
||||
"path/filepath"
|
||||
"os"
|
||||
"strings"
|
||||
)
|
||||
|
||||
const version = "0.1"
|
||||
const version = "1.0.0"
|
||||
const extension = ".asl"
|
||||
const sqfextension = ".sqf"
|
||||
|
||||
type ASLFile struct {
|
||||
in string
|
||||
out string
|
||||
newname string
|
||||
}
|
||||
|
||||
var recursive bool = false
|
||||
var pretty bool = false
|
||||
var exit bool = false
|
||||
var aslFiles []ASLFile
|
||||
var inDir string
|
||||
|
||||
func usage() {
|
||||
fmt.Println("Usage: asl [-v|-r|-pretty] <input file/folder> [<output file/folder>]\n")
|
||||
fmt.Println("Usage: asl [-v|-r|-pretty|--help] <input directory> <output directory>\n")
|
||||
fmt.Println("-v (optional) shows asl version")
|
||||
fmt.Println("-r (optional) recursivly compile all asl files in folder")
|
||||
fmt.Println("-pretty (optional) activates pretty printing\n")
|
||||
fmt.Println("<input file/folder> file or directory to compile")
|
||||
fmt.Println("<output file/folder> (optional) output file/folder, if not set, files will be created alongside their asl files")
|
||||
fmt.Println("--help (optional) shows usage\n")
|
||||
fmt.Println("<input directory> directory to compile")
|
||||
fmt.Println("<output directory> output directory, directory structure will be created corresponding to input directory")
|
||||
}
|
||||
|
||||
func flags(flag string) bool {
|
||||
flag = strings.ToLower(flag)
|
||||
|
||||
if flag[0] == '-' {
|
||||
if flag == "-v" {
|
||||
fmt.Println("asl version "+version)
|
||||
exit = true
|
||||
} else if flag == "-r" {
|
||||
recursive = true
|
||||
} else if flag == "-pretty" {
|
||||
pretty = true
|
||||
} else if flag == "--help" {
|
||||
usage()
|
||||
exit = true
|
||||
}
|
||||
|
||||
return true
|
||||
}
|
||||
|
||||
return false
|
||||
}
|
||||
|
||||
func readAslFiles(path string) {
|
||||
dir, err := ioutil.ReadDir(path)
|
||||
|
||||
if err != nil {
|
||||
fmt.Println("Error reading in directory!")
|
||||
return
|
||||
}
|
||||
|
||||
for i := 0; i < len(dir); i++ {
|
||||
name := dir[i].Name()
|
||||
|
||||
if dir[i].IsDir() && recursive {
|
||||
readAslFiles(path+"/"+name)
|
||||
continue
|
||||
}
|
||||
|
||||
if !dir[i].IsDir() && strings.ToLower(filepath.Ext(name)) == extension {
|
||||
in := path+"/"+dir[i].Name()
|
||||
out := "./"+path[len(inDir):len(path)]
|
||||
newname := name[:len(name)-len(filepath.Ext(name))]
|
||||
|
||||
file := ASLFile{in, out, newname}
|
||||
aslFiles = append(aslFiles, file)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func compile(path string) {
|
||||
for i := 0; i < len(aslFiles); i++ {
|
||||
out := path+"/"+aslFiles[i].out+"/"+aslFiles[i].newname+sqfextension
|
||||
fmt.Println(aslFiles[i].in+" -> "+out)
|
||||
code, err := ioutil.ReadFile(aslFiles[i].in)
|
||||
|
||||
if err != nil {
|
||||
fmt.Println("Error reading file: "+aslFiles[i].in)
|
||||
continue
|
||||
}
|
||||
|
||||
token := asl.Tokenize(code)
|
||||
sqf := asl.Parse(token, pretty)
|
||||
|
||||
os.MkdirAll(path+"/"+aslFiles[i].out, 0777)
|
||||
err = ioutil.WriteFile(out, []byte(sqf), 0666)
|
||||
|
||||
if err != nil {
|
||||
fmt.Println("Error writing file: "+aslFiles[i].out)
|
||||
fmt.Println(err)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func main() {
|
||||
// read test file
|
||||
code, _ := ioutil.ReadFile("in/simple.asl")
|
||||
token := asl.Tokenize(code)
|
||||
out := asl.Parse(token, true)
|
||||
args := os.Args
|
||||
|
||||
fmt.Print("OUTPUT:\n-------\n" + out)
|
||||
// flags
|
||||
if len(args) < 2 {
|
||||
usage()
|
||||
return
|
||||
}
|
||||
|
||||
var i int
|
||||
for i = 1; i < len(args) && flags(args[i]); i++ {}
|
||||
|
||||
if exit {
|
||||
return
|
||||
}
|
||||
|
||||
// in/out parameter
|
||||
out := ""
|
||||
|
||||
if i < len(args) {
|
||||
inDir = args[i]
|
||||
i++
|
||||
} else {
|
||||
return
|
||||
}
|
||||
|
||||
if i < len(args) {
|
||||
out = args[i]
|
||||
}
|
||||
|
||||
readAslFiles(inDir)
|
||||
compile(out)
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user