first commit
This commit is contained in:
5
Tesses.CrossLisp.CompileTool/.gitignore
vendored
Normal file
5
Tesses.CrossLisp.CompileTool/.gitignore
vendored
Normal file
@@ -0,0 +1,5 @@
|
|||||||
|
.DS_Store
|
||||||
|
bin
|
||||||
|
obj
|
||||||
|
publish
|
||||||
|
thumbs.db
|
||||||
11
Tesses.CrossLisp.CompileTool/cross.json
Normal file
11
Tesses.CrossLisp.CompileTool/cross.json
Normal file
@@ -0,0 +1,11 @@
|
|||||||
|
{
|
||||||
|
"$schema": "https:\/\/crosslang.tesseslanguage.com\/\/schema\/cross-json-schema.json",
|
||||||
|
"info": {
|
||||||
|
"type": "compile_tool"
|
||||||
|
},
|
||||||
|
"name": "Tesses.CrossLisp.CompileTool",
|
||||||
|
"project_dependencies": [
|
||||||
|
"..\/Tesses.CrossLisp.Runtime"
|
||||||
|
],
|
||||||
|
"version": "1.0.0.0-prod"
|
||||||
|
}
|
||||||
39
Tesses.CrossLisp.CompileTool/src/main.tcross
Normal file
39
Tesses.CrossLisp.CompileTool/src/main.tcross
Normal file
@@ -0,0 +1,39 @@
|
|||||||
|
func RunTool(cfg)
|
||||||
|
{
|
||||||
|
//cfg.Project is the project Subdirfilesystem
|
||||||
|
//cfg.ProjectInfo is the info property parsed from the cross.json file in project root
|
||||||
|
const crossConf = "/cross.json";
|
||||||
|
|
||||||
|
if(!cfg.Project.FileExists(crossConf)) return;
|
||||||
|
var srcDir = "src";
|
||||||
|
var configData = Json.Decode(FS.ReadAllText(FS.Local,crossConf));
|
||||||
|
if(TypeOf(configData.source_directory) != "Undefined")
|
||||||
|
srcDir = configData.source_directory;
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
func walk_for_source(sourceDir)
|
||||||
|
{
|
||||||
|
if(cfg.Project.DirectoryExists(sourceDir))
|
||||||
|
each(var file : cfg.Project.EnumeratePaths(sourceDir))
|
||||||
|
{
|
||||||
|
if(cfg.Project.RegularFileExists(file) && file.GetExtension()==".lisp")
|
||||||
|
{
|
||||||
|
var src = {
|
||||||
|
FileName = file.ToString(),
|
||||||
|
Source = CrossLisp.toCrossLangText(CrossLisp.parseLisp(FS.ReadAllText(cfg.Project, file)))
|
||||||
|
};
|
||||||
|
cfg.GeneratedSource.Add(src);
|
||||||
|
}
|
||||||
|
else if(cfg.Project.DirectoryExists(file))
|
||||||
|
{
|
||||||
|
walk_for_source(file);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
walk_for_source(srcDir);
|
||||||
|
|
||||||
|
|
||||||
|
//this runs with full access to vm so be careful when allowing these
|
||||||
|
}
|
||||||
5
Tesses.CrossLisp.Example/.gitignore
vendored
Normal file
5
Tesses.CrossLisp.Example/.gitignore
vendored
Normal file
@@ -0,0 +1,5 @@
|
|||||||
|
.DS_Store
|
||||||
|
bin
|
||||||
|
obj
|
||||||
|
publish
|
||||||
|
thumbs.db
|
||||||
15
Tesses.CrossLisp.Example/cross.json
Normal file
15
Tesses.CrossLisp.Example/cross.json
Normal file
@@ -0,0 +1,15 @@
|
|||||||
|
{
|
||||||
|
"$schema": "https:\/\/crosslang.tesseslanguage.com\/\/schema\/cross-json-schema.json",
|
||||||
|
"info": {
|
||||||
|
"description": "Change Me",
|
||||||
|
"short_name": "changeme",
|
||||||
|
"short_name_pretty": "Change Me",
|
||||||
|
"type": "console"
|
||||||
|
},
|
||||||
|
"name": "Tesses.CrossLisp.Example",
|
||||||
|
"project_dependencies": [
|
||||||
|
"..\/Tesses.CrossLisp.CompileTool",
|
||||||
|
"..\/Tesses.CrossLisp.Runtime"
|
||||||
|
],
|
||||||
|
"version": "1.0.0.0-prod"
|
||||||
|
}
|
||||||
9
Tesses.CrossLisp.Example/src/main.lisp
Normal file
9
Tesses.CrossLisp.Example/src/main.lisp
Normal file
@@ -0,0 +1,9 @@
|
|||||||
|
(defun print(text)
|
||||||
|
"Print To Console"
|
||||||
|
(call Console "WriteLine" text)
|
||||||
|
)
|
||||||
|
(defun main(args)
|
||||||
|
"My Main Function"
|
||||||
|
(print (* 6 7))
|
||||||
|
1
|
||||||
|
)
|
||||||
5
Tesses.CrossLisp.Runtime/.gitignore
vendored
Normal file
5
Tesses.CrossLisp.Runtime/.gitignore
vendored
Normal file
@@ -0,0 +1,5 @@
|
|||||||
|
.DS_Store
|
||||||
|
bin
|
||||||
|
obj
|
||||||
|
publish
|
||||||
|
thumbs.db
|
||||||
8
Tesses.CrossLisp.Runtime/cross.json
Normal file
8
Tesses.CrossLisp.Runtime/cross.json
Normal file
@@ -0,0 +1,8 @@
|
|||||||
|
{
|
||||||
|
"$schema": "https:\/\/crosslang.tesseslanguage.com\/\/schema\/cross-json-schema.json",
|
||||||
|
"info": {
|
||||||
|
"type": "lib"
|
||||||
|
},
|
||||||
|
"name": "Tesses.CrossLisp.Runtime",
|
||||||
|
"version": "1.0.0.0-prod"
|
||||||
|
}
|
||||||
462
Tesses.CrossLisp.Runtime/src/mylib.tcross
Normal file
462
Tesses.CrossLisp.Runtime/src/mylib.tcross
Normal file
@@ -0,0 +1,462 @@
|
|||||||
|
|
||||||
|
func CrossLisp.isString(v)
|
||||||
|
{
|
||||||
|
if(!TypeIsList(v)) return false;
|
||||||
|
if(v.Length < 2) return false;
|
||||||
|
return v[0] == "$string";
|
||||||
|
}
|
||||||
|
func CrossLisp.getString(v)
|
||||||
|
{
|
||||||
|
if(!CrossLisp.isString(v)) return "";
|
||||||
|
return v[1];
|
||||||
|
}
|
||||||
|
|
||||||
|
func CrossLisp.asCrossLangList(val)
|
||||||
|
{
|
||||||
|
if(TypeIsLong(val)) return val.ToString();
|
||||||
|
if(TypeIsDouble(val)) return val.ToString();
|
||||||
|
if(TypeIsString(val)) return val.Escape(true);
|
||||||
|
|
||||||
|
if(TypeIsList(val))
|
||||||
|
{
|
||||||
|
var str = "[";
|
||||||
|
|
||||||
|
for(var i = 0; i < val.Length; i++)
|
||||||
|
{
|
||||||
|
if(i > 0)
|
||||||
|
str += ", ";
|
||||||
|
str += CrossLisp.asCrossLangList(val[i]);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
return str + "]";
|
||||||
|
}
|
||||||
|
|
||||||
|
return "null";
|
||||||
|
}
|
||||||
|
|
||||||
|
func CrossLisp.toCrossLangExpression(val)
|
||||||
|
{
|
||||||
|
|
||||||
|
|
||||||
|
if(val == "nil") return "[]";
|
||||||
|
if(TypeIsLong(val)) return val.ToString();
|
||||||
|
if(TypeIsDouble(val)) return val.ToString();
|
||||||
|
if(TypeIsString(val)) return val;
|
||||||
|
|
||||||
|
if(TypeIsList(val))
|
||||||
|
{
|
||||||
|
if(val.Length == 0) return "[]";
|
||||||
|
switch(val[0])
|
||||||
|
{
|
||||||
|
case "+":
|
||||||
|
{
|
||||||
|
var fnCall = "(";
|
||||||
|
|
||||||
|
if(val.Length == 1)
|
||||||
|
fnCall += "0";
|
||||||
|
|
||||||
|
for(var i = 1; i < val.Length; i++)
|
||||||
|
{
|
||||||
|
if(i > 1)
|
||||||
|
fnCall += " + ";
|
||||||
|
fnCall += CrossLisp.toCrossLangExpression(val[i]);
|
||||||
|
}
|
||||||
|
|
||||||
|
return fnCall + ")";
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case "-":
|
||||||
|
{
|
||||||
|
var fnCall = "(";
|
||||||
|
|
||||||
|
if(val.Length == 1)
|
||||||
|
fnCall += "0";
|
||||||
|
|
||||||
|
for(var i = 1; i < val.Length; i++)
|
||||||
|
{
|
||||||
|
if(i > 1)
|
||||||
|
fnCall += " - ";
|
||||||
|
fnCall += CrossLisp.toCrossLangExpression(val[i]);
|
||||||
|
}
|
||||||
|
|
||||||
|
return fnCall + ")";
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case "*":
|
||||||
|
{
|
||||||
|
var fnCall = "(";
|
||||||
|
|
||||||
|
if(val.Length == 1)
|
||||||
|
fnCall += "0";
|
||||||
|
|
||||||
|
for(var i = 1; i < val.Length; i++)
|
||||||
|
{
|
||||||
|
if(i > 1)
|
||||||
|
fnCall += " * ";
|
||||||
|
fnCall += CrossLisp.toCrossLangExpression(val[i]);
|
||||||
|
}
|
||||||
|
|
||||||
|
return fnCall + ")";
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case "/":
|
||||||
|
{
|
||||||
|
var fnCall = "(";
|
||||||
|
|
||||||
|
if(val.Length == 1)
|
||||||
|
fnCall += "0";
|
||||||
|
|
||||||
|
for(var i = 1; i < val.Length; i++)
|
||||||
|
{
|
||||||
|
if(i > 1)
|
||||||
|
fnCall += " / ";
|
||||||
|
fnCall += CrossLisp.toCrossLangExpression(val[i]);
|
||||||
|
}
|
||||||
|
|
||||||
|
return fnCall + ")";
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case "%":
|
||||||
|
{
|
||||||
|
var fnCall = "(";
|
||||||
|
|
||||||
|
if(val.Length == 1)
|
||||||
|
fnCall += "0";
|
||||||
|
|
||||||
|
for(var i = 1; i < val.Length; i++)
|
||||||
|
{
|
||||||
|
if(i > 1)
|
||||||
|
fnCall += " % ";
|
||||||
|
fnCall += CrossLisp.toCrossLangExpression(val[i]);
|
||||||
|
}
|
||||||
|
|
||||||
|
return fnCall + ")";
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case "quote":
|
||||||
|
{
|
||||||
|
if(val.Count > 1)
|
||||||
|
return CrossLisp.asCrossLangList(val[1]);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case "call":
|
||||||
|
{
|
||||||
|
if(val.Length >= 3 && CrossLisp.isString(val[2]))
|
||||||
|
{
|
||||||
|
var fnCall = "(" + CrossLisp.toCrossLangExpression(val[1]) + $").{CrossLisp.getString(val[2])}(";
|
||||||
|
for(var i = 3; i < val.Length; i++)
|
||||||
|
{
|
||||||
|
if(i > 3)
|
||||||
|
fnCall += ", ";
|
||||||
|
fnCall += CrossLisp.toCrossLangExpression(val[i]);
|
||||||
|
}
|
||||||
|
return fnCall + ")";
|
||||||
|
}
|
||||||
|
//(call Console "WriteLine" args...)
|
||||||
|
}
|
||||||
|
case "eval":
|
||||||
|
{
|
||||||
|
if(val.Length == 2)
|
||||||
|
{
|
||||||
|
return "VM.Eval(\"return \" + CrossLisp.toCrossLangExpression(" + CrossLisp.toCrossLangExpression(val[1]) + ") + \";\")";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case "setq":
|
||||||
|
{
|
||||||
|
//(setq val 42)
|
||||||
|
if(val.Length == 3 && TypeIsString(name))
|
||||||
|
{
|
||||||
|
return "(" + name + "=" + CrossLisp.toCrossLangExpression(val[2]) + ")";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case "dict":
|
||||||
|
{
|
||||||
|
var dict = "{";
|
||||||
|
for(var i = 1; i < val.Length; i++)
|
||||||
|
{
|
||||||
|
if(i > 1)
|
||||||
|
dict += ", ";
|
||||||
|
if(TypeIsList(val[i]) && val[i].Length == 2 && TypeIsString(val[i][0]))
|
||||||
|
{
|
||||||
|
dict += val[i][0] + " = " + CrossLisp.toCrossLangExpression(val[i][1]);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
throw "Must look like this (dict (key1 value) (key2 value))";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return dict + "}";
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case "$string":
|
||||||
|
{
|
||||||
|
if(val.Length == 2)
|
||||||
|
{
|
||||||
|
return val[1].Escape(true);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
{
|
||||||
|
var fnCall = val[0] + "(";
|
||||||
|
|
||||||
|
for(var i = 1; i < val.Length; i++)
|
||||||
|
{
|
||||||
|
if(i > 1)
|
||||||
|
fnCall += ", ";
|
||||||
|
fnCall += CrossLisp.toCrossLangExpression(val[i]);
|
||||||
|
}
|
||||||
|
|
||||||
|
return fnCall + ")";
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return "[]";
|
||||||
|
}
|
||||||
|
|
||||||
|
func CrossLisp.toCrossLangText(list)
|
||||||
|
{
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
var code = "";
|
||||||
|
each(var item : list)
|
||||||
|
{
|
||||||
|
if(TypeIsList(item) && item.Length > 0)
|
||||||
|
{
|
||||||
|
if(item[0] == "defun")
|
||||||
|
{
|
||||||
|
if(TypeIsString(item[1]))
|
||||||
|
{
|
||||||
|
var hasDoc = false;
|
||||||
|
if(CrossLisp.isString(item[3]))
|
||||||
|
{
|
||||||
|
hasDoc=true;
|
||||||
|
code += "\n/^ " + CrossLisp.getString(item[3]).Replace("^","^^") + " ^/\n";
|
||||||
|
}
|
||||||
|
|
||||||
|
code += $"func {item[1]}(";
|
||||||
|
if(TypeIsList(item[2]))
|
||||||
|
{
|
||||||
|
for(var i = 0; i < item[2].Length; i++)
|
||||||
|
{
|
||||||
|
if(i > 0) code += ", ";
|
||||||
|
code += item[2][i];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
code += "){";
|
||||||
|
for(var i = hasDoc ? 4 : 3; i < item.Length; i++)
|
||||||
|
{
|
||||||
|
if(i + 1 == item.Length)
|
||||||
|
code += "return ";
|
||||||
|
code += CrossLisp.toCrossLangExpression(item[i]);
|
||||||
|
code += ";";
|
||||||
|
}
|
||||||
|
|
||||||
|
code += "}";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return code;
|
||||||
|
}
|
||||||
|
func CrossLisp.parseLisp(text)
|
||||||
|
{
|
||||||
|
//(+ "Hi" 42)
|
||||||
|
//["+",["$string","Hi"], 42]
|
||||||
|
|
||||||
|
//(+ 'hi 42)
|
||||||
|
//["+",["quote",["hi"]],42]
|
||||||
|
|
||||||
|
var builder = "";
|
||||||
|
|
||||||
|
var tokens = [];
|
||||||
|
|
||||||
|
func flush()
|
||||||
|
{
|
||||||
|
if(builder.Length > 0) {
|
||||||
|
if(builder[0] >= '0' && builder[0] <= '9')
|
||||||
|
{
|
||||||
|
if(builder.Contains("."))
|
||||||
|
{
|
||||||
|
const dbl = ParseDouble(builder);
|
||||||
|
tokens.Add({
|
||||||
|
type = "ident",
|
||||||
|
value = dbl
|
||||||
|
});
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
const lng = ParseLong(builder);
|
||||||
|
tokens.Add({
|
||||||
|
type = "ident",
|
||||||
|
value = lng
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
|
||||||
|
tokens.Add({
|
||||||
|
type = "ident",
|
||||||
|
value = builder
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
builder = "";
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
for(var i = 0; i < text.Length; i++)
|
||||||
|
{
|
||||||
|
switch(text[i])
|
||||||
|
{
|
||||||
|
case '(':
|
||||||
|
{
|
||||||
|
flush();
|
||||||
|
tokens.Add({
|
||||||
|
type="("
|
||||||
|
});
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case ')':
|
||||||
|
{
|
||||||
|
flush();
|
||||||
|
tokens.Add({
|
||||||
|
type=")"
|
||||||
|
});
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case '\'':
|
||||||
|
{
|
||||||
|
flush();
|
||||||
|
tokens.Add({
|
||||||
|
type="'"
|
||||||
|
});
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
|
||||||
|
break;
|
||||||
|
case '\\':
|
||||||
|
builder += text[++i];
|
||||||
|
break;
|
||||||
|
case '\"':
|
||||||
|
{
|
||||||
|
flush();
|
||||||
|
i++;
|
||||||
|
var strtext = "";
|
||||||
|
for(; (i < text.Length) && text[i] != '\"'; i++)
|
||||||
|
{
|
||||||
|
if(text[i] == '\\')
|
||||||
|
{
|
||||||
|
i++;
|
||||||
|
if(i < text.Length)
|
||||||
|
{
|
||||||
|
if(text[i] == 'n')
|
||||||
|
{
|
||||||
|
strtext += "\n";
|
||||||
|
}
|
||||||
|
else if(text[i] == 'r')
|
||||||
|
{
|
||||||
|
strtext += "\r";
|
||||||
|
}
|
||||||
|
else if(text[i] == 't')
|
||||||
|
{
|
||||||
|
strtext += "\t";
|
||||||
|
}
|
||||||
|
else if(text[i] == 'v')
|
||||||
|
{
|
||||||
|
strtext += "\v";
|
||||||
|
}
|
||||||
|
else if(text[i] == 'e')
|
||||||
|
{
|
||||||
|
strtext += "\e";
|
||||||
|
}
|
||||||
|
else if(text[i] == 'x')
|
||||||
|
{
|
||||||
|
if(i + 2 < text.Length)
|
||||||
|
{
|
||||||
|
i++;
|
||||||
|
strtext += Net.Http.UrlPathDecode($"%{text[i]}{text[i+1]}");
|
||||||
|
i++;
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
strtext += text[i];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
strtext += text[i];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
tokens.Add({
|
||||||
|
type = "$string",
|
||||||
|
value = strtext
|
||||||
|
});
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case ' ':
|
||||||
|
case '\n':
|
||||||
|
case '\r':
|
||||||
|
case '\t':
|
||||||
|
flush();
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
builder += text[i];
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
flush();
|
||||||
|
|
||||||
|
|
||||||
|
var off = 0;
|
||||||
|
|
||||||
|
|
||||||
|
func parse()
|
||||||
|
{
|
||||||
|
if(tokens[off].type == "'")
|
||||||
|
{
|
||||||
|
off++;
|
||||||
|
return ["quote",parse()];
|
||||||
|
}
|
||||||
|
if(tokens[off].type == "(")
|
||||||
|
{
|
||||||
|
off++;
|
||||||
|
var ls = [];
|
||||||
|
while(tokens[off].type != ")")
|
||||||
|
{
|
||||||
|
ls.Add(parse());
|
||||||
|
}
|
||||||
|
off++;
|
||||||
|
return ls;
|
||||||
|
}
|
||||||
|
|
||||||
|
if(tokens[off].type == "ident")
|
||||||
|
{
|
||||||
|
return tokens[off++].value;
|
||||||
|
}
|
||||||
|
|
||||||
|
if(tokens[off].type == "$string")
|
||||||
|
{
|
||||||
|
return ["$string",tokens[off++].value];
|
||||||
|
}
|
||||||
|
|
||||||
|
return [];
|
||||||
|
}
|
||||||
|
|
||||||
|
const ls = [];
|
||||||
|
|
||||||
|
while(off < tokens.Length)
|
||||||
|
ls.Add(parse());
|
||||||
|
return ls;
|
||||||
|
}
|
||||||
|
|
||||||
|
//Console.WriteLine(CrossLisp.toCrossLangText(parseLisp("")));
|
||||||
Reference in New Issue
Block a user