First commit
This commit is contained in:
commit
5c8d97d8d4
|
@ -0,0 +1,3 @@
|
||||||
|
bin
|
||||||
|
bin-tmp
|
||||||
|
obj
|
|
@ -0,0 +1,157 @@
|
||||||
|
# GNU LESSER GENERAL PUBLIC LICENSE
|
||||||
|
|
||||||
|
Version 3, 29 June 2007
|
||||||
|
|
||||||
|
Copyright (C) 2007 Free Software Foundation, Inc.
|
||||||
|
<https://fsf.org/>
|
||||||
|
|
||||||
|
Everyone is permitted to copy and distribute verbatim copies of this
|
||||||
|
license document, but changing it is not allowed.
|
||||||
|
|
||||||
|
This version of the GNU Lesser General Public License incorporates the
|
||||||
|
terms and conditions of version 3 of the GNU General Public License,
|
||||||
|
supplemented by the additional permissions listed below.
|
||||||
|
|
||||||
|
## 0. Additional Definitions.
|
||||||
|
|
||||||
|
As used herein, "this License" refers to version 3 of the GNU Lesser
|
||||||
|
General Public License, and the "GNU GPL" refers to version 3 of the
|
||||||
|
GNU General Public License.
|
||||||
|
|
||||||
|
"The Library" refers to a covered work governed by this License, other
|
||||||
|
than an Application or a Combined Work as defined below.
|
||||||
|
|
||||||
|
An "Application" is any work that makes use of an interface provided
|
||||||
|
by the Library, but which is not otherwise based on the Library.
|
||||||
|
Defining a subclass of a class defined by the Library is deemed a mode
|
||||||
|
of using an interface provided by the Library.
|
||||||
|
|
||||||
|
A "Combined Work" is a work produced by combining or linking an
|
||||||
|
Application with the Library. The particular version of the Library
|
||||||
|
with which the Combined Work was made is also called the "Linked
|
||||||
|
Version".
|
||||||
|
|
||||||
|
The "Minimal Corresponding Source" for a Combined Work means the
|
||||||
|
Corresponding Source for the Combined Work, excluding any source code
|
||||||
|
for portions of the Combined Work that, considered in isolation, are
|
||||||
|
based on the Application, and not on the Linked Version.
|
||||||
|
|
||||||
|
The "Corresponding Application Code" for a Combined Work means the
|
||||||
|
object code and/or source code for the Application, including any data
|
||||||
|
and utility programs needed for reproducing the Combined Work from the
|
||||||
|
Application, but excluding the System Libraries of the Combined Work.
|
||||||
|
|
||||||
|
## 1. Exception to Section 3 of the GNU GPL.
|
||||||
|
|
||||||
|
You may convey a covered work under sections 3 and 4 of this License
|
||||||
|
without being bound by section 3 of the GNU GPL.
|
||||||
|
|
||||||
|
## 2. Conveying Modified Versions.
|
||||||
|
|
||||||
|
If you modify a copy of the Library, and, in your modifications, a
|
||||||
|
facility refers to a function or data to be supplied by an Application
|
||||||
|
that uses the facility (other than as an argument passed when the
|
||||||
|
facility is invoked), then you may convey a copy of the modified
|
||||||
|
version:
|
||||||
|
|
||||||
|
- a) under this License, provided that you make a good faith effort
|
||||||
|
to ensure that, in the event an Application does not supply the
|
||||||
|
function or data, the facility still operates, and performs
|
||||||
|
whatever part of its purpose remains meaningful, or
|
||||||
|
- b) under the GNU GPL, with none of the additional permissions of
|
||||||
|
this License applicable to that copy.
|
||||||
|
|
||||||
|
## 3. Object Code Incorporating Material from Library Header Files.
|
||||||
|
|
||||||
|
The object code form of an Application may incorporate material from a
|
||||||
|
header file that is part of the Library. You may convey such object
|
||||||
|
code under terms of your choice, provided that, if the incorporated
|
||||||
|
material is not limited to numerical parameters, data structure
|
||||||
|
layouts and accessors, or small macros, inline functions and templates
|
||||||
|
(ten or fewer lines in length), you do both of the following:
|
||||||
|
|
||||||
|
- a) Give prominent notice with each copy of the object code that
|
||||||
|
the Library is used in it and that the Library and its use are
|
||||||
|
covered by this License.
|
||||||
|
- b) Accompany the object code with a copy of the GNU GPL and this
|
||||||
|
license document.
|
||||||
|
|
||||||
|
## 4. Combined Works.
|
||||||
|
|
||||||
|
You may convey a Combined Work under terms of your choice that, taken
|
||||||
|
together, effectively do not restrict modification of the portions of
|
||||||
|
the Library contained in the Combined Work and reverse engineering for
|
||||||
|
debugging such modifications, if you also do each of the following:
|
||||||
|
|
||||||
|
- a) Give prominent notice with each copy of the Combined Work that
|
||||||
|
the Library is used in it and that the Library and its use are
|
||||||
|
covered by this License.
|
||||||
|
- b) Accompany the Combined Work with a copy of the GNU GPL and this
|
||||||
|
license document.
|
||||||
|
- c) For a Combined Work that displays copyright notices during
|
||||||
|
execution, include the copyright notice for the Library among
|
||||||
|
these notices, as well as a reference directing the user to the
|
||||||
|
copies of the GNU GPL and this license document.
|
||||||
|
- d) Do one of the following:
|
||||||
|
- 0) Convey the Minimal Corresponding Source under the terms of
|
||||||
|
this License, and the Corresponding Application Code in a form
|
||||||
|
suitable for, and under terms that permit, the user to
|
||||||
|
recombine or relink the Application with a modified version of
|
||||||
|
the Linked Version to produce a modified Combined Work, in the
|
||||||
|
manner specified by section 6 of the GNU GPL for conveying
|
||||||
|
Corresponding Source.
|
||||||
|
- 1) Use a suitable shared library mechanism for linking with
|
||||||
|
the Library. A suitable mechanism is one that (a) uses at run
|
||||||
|
time a copy of the Library already present on the user's
|
||||||
|
computer system, and (b) will operate properly with a modified
|
||||||
|
version of the Library that is interface-compatible with the
|
||||||
|
Linked Version.
|
||||||
|
- e) Provide Installation Information, but only if you would
|
||||||
|
otherwise be required to provide such information under section 6
|
||||||
|
of the GNU GPL, and only to the extent that such information is
|
||||||
|
necessary to install and execute a modified version of the
|
||||||
|
Combined Work produced by recombining or relinking the Application
|
||||||
|
with a modified version of the Linked Version. (If you use option
|
||||||
|
4d0, the Installation Information must accompany the Minimal
|
||||||
|
Corresponding Source and Corresponding Application Code. If you
|
||||||
|
use option 4d1, you must provide the Installation Information in
|
||||||
|
the manner specified by section 6 of the GNU GPL for conveying
|
||||||
|
Corresponding Source.)
|
||||||
|
|
||||||
|
## 5. Combined Libraries.
|
||||||
|
|
||||||
|
You may place library facilities that are a work based on the Library
|
||||||
|
side by side in a single library together with other library
|
||||||
|
facilities that are not Applications and are not covered by this
|
||||||
|
License, and convey such a combined library under terms of your
|
||||||
|
choice, if you do both of the following:
|
||||||
|
|
||||||
|
- a) Accompany the combined library with a copy of the same work
|
||||||
|
based on the Library, uncombined with any other library
|
||||||
|
facilities, conveyed under the terms of this License.
|
||||||
|
- b) Give prominent notice with the combined library that part of it
|
||||||
|
is a work based on the Library, and explaining where to find the
|
||||||
|
accompanying uncombined form of the same work.
|
||||||
|
|
||||||
|
## 6. Revised Versions of the GNU Lesser General Public License.
|
||||||
|
|
||||||
|
The Free Software Foundation may publish revised and/or new versions
|
||||||
|
of the GNU Lesser General Public License from time to time. Such new
|
||||||
|
versions will be similar in spirit to the present version, but may
|
||||||
|
differ in detail to address new problems or concerns.
|
||||||
|
|
||||||
|
Each version is given a distinguishing version number. If the Library
|
||||||
|
as you received it specifies that a certain numbered version of the
|
||||||
|
GNU Lesser General Public License "or any later version" applies to
|
||||||
|
it, you have the option of following the terms and conditions either
|
||||||
|
of that published version or of any later version published by the
|
||||||
|
Free Software Foundation. If the Library as you received it does not
|
||||||
|
specify a version number of the GNU Lesser General Public License, you
|
||||||
|
may choose any version of the GNU Lesser General Public License ever
|
||||||
|
published by the Free Software Foundation.
|
||||||
|
|
||||||
|
If the Library as you received it specifies that a proxy can decide
|
||||||
|
whether future versions of the GNU Lesser General Public License shall
|
||||||
|
apply, that proxy's public statement of acceptance of any version is
|
||||||
|
permanent authorization for you to choose that version for the
|
||||||
|
Library.
|
|
@ -0,0 +1,15 @@
|
||||||
|
# CrossLang Essentials
|
||||||
|
|
||||||
|
> :warning: **NOT READY FOR PRODUCTION**
|
||||||
|
|
||||||
|
[CrossLang](https://gitea.site.tesses.net/tesses50/crosslang) is required to build this
|
||||||
|
|
||||||
|
# To Build
|
||||||
|
```bash
|
||||||
|
./script.sh
|
||||||
|
```
|
||||||
|
|
||||||
|
# To Install
|
||||||
|
```bash
|
||||||
|
./install.sh
|
||||||
|
```
|
|
@ -0,0 +1,11 @@
|
||||||
|
{
|
||||||
|
"name": "Tesses.CrossLang.BuildEssentials",
|
||||||
|
"version": "1.0.0.0-prod",
|
||||||
|
"info": {
|
||||||
|
"maintainer": "Mike Nolan",
|
||||||
|
"type": "lib",
|
||||||
|
"repo": "https://gitea.site.tesses.net/tesses50/crosslang/crosslang-libs",
|
||||||
|
"homepage": "https://crosslang.tesseslanguage.com/",
|
||||||
|
"license": "LGPLv3"
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,11 @@
|
||||||
|
func main(args)
|
||||||
|
{
|
||||||
|
var pm = Tesses.CrossLang.PackageManager();
|
||||||
|
//pm.Offline=true;
|
||||||
|
//Console.WriteLine(pm.GetLatest("MyPackage"));
|
||||||
|
//Console.WriteLine(Json.Encode(pm.ParseFileName("BeautifulApp-John-1.0.0.0-prod.crvm")));
|
||||||
|
|
||||||
|
var tool = Tesses.CrossLang.BuildTool(pm);
|
||||||
|
tool.BuildProject(args[1]);
|
||||||
|
|
||||||
|
}
|
|
@ -0,0 +1,136 @@
|
||||||
|
func Tesses.CrossLang.PackageManager()
|
||||||
|
{
|
||||||
|
func ParseFileName(name)
|
||||||
|
{
|
||||||
|
|
||||||
|
var index = name.LastIndexOf('.');
|
||||||
|
if(index == -1) throw "We expect an extension";
|
||||||
|
if(name.Substring(index) != ".crvm") throw "We expect the extension .crvm";
|
||||||
|
name = name.Substring(0,index);
|
||||||
|
//Name-VERSION-[dev|alpha|beta|prod]
|
||||||
|
|
||||||
|
var lastIndex = name.LastIndexOf('-');
|
||||||
|
var verStage = name.Substring(lastIndex+1);
|
||||||
|
var versionStr = verStage;
|
||||||
|
if(verStage == "dev" || verStage == "alpha" || verStage == "beta" || verStage == "prod")
|
||||||
|
{
|
||||||
|
var lastIndex2 = name.LastIndexOf('-', lastIndex-1);
|
||||||
|
return {
|
||||||
|
Name = name.Substring(0,lastIndex2),
|
||||||
|
Version = name.Substring(lastIndex2+1)
|
||||||
|
};
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
return {
|
||||||
|
Name = name.Substring(0,lastIndex),
|
||||||
|
Version = name.Substring(lastIndex+1)
|
||||||
|
};
|
||||||
|
}
|
||||||
|
}
|
||||||
|
var configRoot = Path.FromString(Env.Config) / "Tesses" / "CrossLang";
|
||||||
|
var packageCache = configRoot / "PackageCache";
|
||||||
|
FS.Local.CreateDirectory(packageCache);
|
||||||
|
func FileReadByteArray(fs,path)
|
||||||
|
{
|
||||||
|
var f = fs.OpenFile(path,"rb");
|
||||||
|
var ms = FS.MemoryStream(true);
|
||||||
|
f.CopyTo(ms);
|
||||||
|
var buff = ms.GetBytes();
|
||||||
|
f.Close();
|
||||||
|
return buff;
|
||||||
|
}
|
||||||
|
func FileReadString (fs,path) {
|
||||||
|
var buff = FileReadByteArray(fs,path).ToString();
|
||||||
|
ms.Close();
|
||||||
|
return text;
|
||||||
|
}
|
||||||
|
return {
|
||||||
|
Offline = false,
|
||||||
|
ParseFileName,
|
||||||
|
GetPackageServers = ()=>{
|
||||||
|
var packageConfigFile = configRoot / "package_servers.json";
|
||||||
|
if(FS.Local.RegularFileExists(packageConfigFile))
|
||||||
|
{
|
||||||
|
return Json.Decode(FileReadString(FS.Local, packageConfigFile));
|
||||||
|
}
|
||||||
|
return ["https://cpkg.tesseslanguage.com/"];
|
||||||
|
},
|
||||||
|
GetPackage = (this,name, version) =>
|
||||||
|
{
|
||||||
|
var v = Tesses.CrossLang.Version.Parse(version);
|
||||||
|
var useCache = v.Stage != Tesses.CrossLang.Version.Dev;
|
||||||
|
var pkgFile = packageCache / name / v.ToString();
|
||||||
|
if(useCache && FS.Local.RegularFileExists(pkgFile))
|
||||||
|
{
|
||||||
|
return FileReadByteArray(FS.Local,pkgFile);
|
||||||
|
}
|
||||||
|
if(this.Offline) return null;
|
||||||
|
|
||||||
|
each(var item : this.GetPackageServers())
|
||||||
|
{
|
||||||
|
//https://cpkg.tesseslanguage.com/api/v1/download?name=MyPackage&version=1.0.0.0-prod
|
||||||
|
var uri = $"{item.TrimEnd('/')}/api/v1/download?name={Net.Http.UrlEncode(name)}&version={Net.Http.UrlEncode(version)}";
|
||||||
|
var req = Net.Http.MakeRequest(uri);
|
||||||
|
if(req.StatusCode == 200)
|
||||||
|
{
|
||||||
|
var strm = FS.MemoryStream(true);
|
||||||
|
req.CopyToStream(strm);
|
||||||
|
|
||||||
|
if(useCache) {
|
||||||
|
FS.Local.CreateDirectory(packageCache / name);
|
||||||
|
var f = FS.Local.OpenFile(pkgFile,"wb");
|
||||||
|
strm.Seek(0,0);
|
||||||
|
strm.CopyTo(f);
|
||||||
|
f.Close();
|
||||||
|
}
|
||||||
|
var data = strm.GetBytes();
|
||||||
|
strm.Close();
|
||||||
|
req.Close();
|
||||||
|
return data;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return null;
|
||||||
|
},
|
||||||
|
GetLatest = (this,name) => {
|
||||||
|
var pkgServers = this.GetPackageServers();
|
||||||
|
if(this.Offline || pkgServers.Count == 0)
|
||||||
|
{
|
||||||
|
//user has declared they are offline or don't have packageServers look through packages locally
|
||||||
|
var version = Tesses.CrossLang.Version.Create(0,0,0,0,0);
|
||||||
|
var configRoot = Path.FromString(Env.Config) / "Tesses" / "CrossLang";
|
||||||
|
var dir = configRoot / "PackageCache" / name;
|
||||||
|
if(FS.Local.DirectoryExists(dir))
|
||||||
|
each(var f : FS.Local.EnumeratePaths(dir))
|
||||||
|
{
|
||||||
|
var v = Tesses.CrossLang.Version.Parse(f.GetFileName());
|
||||||
|
if(v >= version)
|
||||||
|
{
|
||||||
|
version = v;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if(version.VersionInt == 0) return null;
|
||||||
|
return version.ToString();
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
each(var item : pkgServers)
|
||||||
|
{
|
||||||
|
var uri = $"{item.TrimEnd('/')}/api/v1/latest?name={Net.Http.UrlEncode(name)}";
|
||||||
|
var req = Net.Http.MakeRequest(uri);
|
||||||
|
if(req.StatusCode == 200)
|
||||||
|
{
|
||||||
|
var res0 = req.ReadAsString();
|
||||||
|
|
||||||
|
var res = Json.Decode(res0);
|
||||||
|
req.Close();
|
||||||
|
return res.version;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
}
|
|
@ -0,0 +1,227 @@
|
||||||
|
func Tesses.CrossLang.BuildTool(pm)
|
||||||
|
{
|
||||||
|
func copyFile(src,dest)
|
||||||
|
{
|
||||||
|
var src = FS.Local.OpenFile(src,"rb");
|
||||||
|
var dest = FS.Local.OpenFile(dest, "wb");
|
||||||
|
src.CopyTo(dest);
|
||||||
|
src.Close();
|
||||||
|
dest.Close();
|
||||||
|
}
|
||||||
|
|
||||||
|
return {
|
||||||
|
DirectoriesCompiled = [],
|
||||||
|
FileReadString = (fs,path) =>{
|
||||||
|
var f = fs.OpenFile(path,"rb");
|
||||||
|
var ms = FS.MemoryStream(true);
|
||||||
|
f.CopyTo(ms);
|
||||||
|
var text = ms.GetBytes().ToString();
|
||||||
|
f.Close();
|
||||||
|
ms.Close();
|
||||||
|
return text;
|
||||||
|
},
|
||||||
|
GetPackageDependencies = (this,name,version,dir)=>{
|
||||||
|
var dep = pm.GetPackage(name,version);
|
||||||
|
if(TypeOf(dep) == "Null") throw $"Package {name} with version {version} does not exist";
|
||||||
|
var pkgPath = dir / $"{name}-{version}.crvm";
|
||||||
|
var strm = FS.Local.OpenFile(pkgPath,"wb");
|
||||||
|
strm.WriteBlock(dep,0,dep.Count);
|
||||||
|
strm.Close();
|
||||||
|
var ms = MemoryStream(true);
|
||||||
|
ms.WriteBlock(dep,0,dep.Count);
|
||||||
|
ms.Seek(0,0);
|
||||||
|
var package = Tesses.CrossLang.CrossVMFile();
|
||||||
|
package.Load(ms);
|
||||||
|
ms.Close();
|
||||||
|
|
||||||
|
var deps = [];
|
||||||
|
|
||||||
|
each(var dep : package.Dependencies)
|
||||||
|
{
|
||||||
|
deps.Add(this.GetPackageDependencies(dep.Name, dep.Version, dir));
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
return {
|
||||||
|
Name = name,
|
||||||
|
Version = version,
|
||||||
|
Info = package.Info,
|
||||||
|
Dependencies = deps,
|
||||||
|
Output = pkgPath
|
||||||
|
};
|
||||||
|
},
|
||||||
|
BuildProject = (this,projectDirectory)=>{
|
||||||
|
|
||||||
|
var dir = FS.MakeFull(projectDirectory);
|
||||||
|
var dirStr = dir.ToString();
|
||||||
|
|
||||||
|
each(var item : this.DirectoriesCompiled)
|
||||||
|
{
|
||||||
|
if(item.Path == dirStr) return item.Data;
|
||||||
|
}
|
||||||
|
|
||||||
|
var crossConf = dir / "cross.json";
|
||||||
|
if(FS.Local.FileExists(crossConf))
|
||||||
|
{
|
||||||
|
var configData = Json.Decode(this.FileReadString(FS.Local,crossConf));
|
||||||
|
var info = {type = "console"};
|
||||||
|
var name = "out";
|
||||||
|
var version = "1.0.0.0-prod";
|
||||||
|
var outputDir = "bin";
|
||||||
|
var objDir = "obj";
|
||||||
|
var srcDir = "src";
|
||||||
|
var resDir = "res";
|
||||||
|
if(TypeOf(configData.name) != "Undefined")
|
||||||
|
name = configData.name;
|
||||||
|
|
||||||
|
if(TypeOf(configData.version) != "Undefined")
|
||||||
|
version = configData.version;
|
||||||
|
if(TypeOf(configData.bin_directory) != "Undefined")
|
||||||
|
outputDir = configData.bin_directory;
|
||||||
|
|
||||||
|
if(TypeOf(configData.obj_directory) != "Undefined")
|
||||||
|
outputDir = configData.obj_directory;
|
||||||
|
if(TypeOf(configData.source_directory) != "Undefined")
|
||||||
|
srcDir = configData.source_directory;
|
||||||
|
if(TypeOf(configData.resource_directory) != "Undefined")
|
||||||
|
resDir = configData.resource_directory;
|
||||||
|
if(TypeOf(configData.info) != "Undefined")
|
||||||
|
info = configData.info;
|
||||||
|
|
||||||
|
FS.Local.CreateDirectory(dir / outputDir);
|
||||||
|
|
||||||
|
FS.Local.CreateDirectory(dir / objDir / "packages");
|
||||||
|
|
||||||
|
FS.Local.CreateDirectory(dir/resDir);
|
||||||
|
|
||||||
|
var dependencies = [];
|
||||||
|
if(TypeOf(configData.project_dependencies) == "List")
|
||||||
|
{
|
||||||
|
each(var dep : configData.project_dependencies)
|
||||||
|
{
|
||||||
|
dependencies.Add(this.BuildProject(dep));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
var sources = [];
|
||||||
|
if(TypeOf(configData.dependencies) == "List")
|
||||||
|
{
|
||||||
|
each(var dep : configData.project_dependencies)
|
||||||
|
{
|
||||||
|
dependencies.Add(this.GetPackageDependencies(dep.Name,dep.Version,dir / objDir / "packages"));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
each(var item : this.DirectoriesCompiled)
|
||||||
|
{
|
||||||
|
if(item.Path == dirStr) return item.Data;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
func walk_for_compiling(item,dir2)
|
||||||
|
{
|
||||||
|
if(item.Info.type == "compile_tool")
|
||||||
|
{
|
||||||
|
var newDir = dir / objDir / $"{item.Name}-{item.Version}";
|
||||||
|
FS.Local.CreateDirectory(newDir);
|
||||||
|
var newFile = newDir / $"{item.Name}-{item.Version}.crvm";
|
||||||
|
|
||||||
|
copyFile(item.Output, newFile);
|
||||||
|
each(var item2 : item.Dependencies)
|
||||||
|
{
|
||||||
|
walk_for_compiling(item2, newDir);
|
||||||
|
}
|
||||||
|
//we need to load this
|
||||||
|
var env = VM.CreateEnvironment({});
|
||||||
|
env.RegisterEverything();
|
||||||
|
env.LockRegister();
|
||||||
|
|
||||||
|
env.LoadFileWithDependencies(FS.Local,newFile);
|
||||||
|
env.GetDictionary().RunTool({
|
||||||
|
Project = FS.SubdirFilesystem(FS.Local, dir),
|
||||||
|
ProjectInfo = info,
|
||||||
|
GeneratedSource = sources
|
||||||
|
});
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
copyFile(item.Output, dir2 / $"{item.Name}-{item.Version}.crvm");
|
||||||
|
each(var item2 : item.Dependencies)
|
||||||
|
{
|
||||||
|
walk_for_compiling(item2, dir2);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
var file_deps = [];
|
||||||
|
|
||||||
|
each(var dep : dependencies)
|
||||||
|
{
|
||||||
|
if(dep.Info.type == "lib")
|
||||||
|
{
|
||||||
|
file_deps.Add({
|
||||||
|
Name = dep.Name,
|
||||||
|
Version = dep.Version
|
||||||
|
});
|
||||||
|
}
|
||||||
|
walk_for_compiling(dep,dir / outputDir);
|
||||||
|
}
|
||||||
|
|
||||||
|
func walk_for_source(sourceDir)
|
||||||
|
{
|
||||||
|
each(var file : FS.Local.EnumeratePaths(sourceDir))
|
||||||
|
{
|
||||||
|
if(FS.Local.RegularFileExists(file))
|
||||||
|
{
|
||||||
|
var src = {
|
||||||
|
FileName = file.ToString(),
|
||||||
|
Source = this.FileReadString(FS.Local, file)
|
||||||
|
};
|
||||||
|
sources.Add(src);
|
||||||
|
}
|
||||||
|
else if(FS.Local.DirectoryExists(file))
|
||||||
|
{
|
||||||
|
walk_for_source(file);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
walk_for_source(dir / srcDir);
|
||||||
|
|
||||||
|
|
||||||
|
var output = $"{name}-{version}.crvm";
|
||||||
|
var outFile = FS.Local.OpenFile(dir / outputDir / output,"wb");
|
||||||
|
|
||||||
|
var result = VM.Compile({
|
||||||
|
Name = name,
|
||||||
|
Version = version,
|
||||||
|
Sources = sources,
|
||||||
|
Info = Json.Encode(info),
|
||||||
|
ResourceFileSystem = FS.SubdirFilesystem(FS.Local, dir / resDir),
|
||||||
|
Dependencies = file_deps,
|
||||||
|
Output = outFile
|
||||||
|
});
|
||||||
|
|
||||||
|
outFile.Close();
|
||||||
|
if(!result.Success)
|
||||||
|
{
|
||||||
|
throw result.Reason;
|
||||||
|
}
|
||||||
|
|
||||||
|
var myData = {
|
||||||
|
Name = name,
|
||||||
|
Version = version,
|
||||||
|
Info = info,
|
||||||
|
Output = dir / outputDir / output,
|
||||||
|
Dependencies = dependencies
|
||||||
|
};
|
||||||
|
this.DirectoriesCompiled.Add({
|
||||||
|
Path = dirStr,
|
||||||
|
Data = myData
|
||||||
|
});
|
||||||
|
|
||||||
|
return myData;
|
||||||
|
}
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
}
|
|
@ -0,0 +1,149 @@
|
||||||
|
func Tesses.CrossLang.CrossVMFile()
|
||||||
|
{
|
||||||
|
return {
|
||||||
|
Info = "",
|
||||||
|
Name = "",
|
||||||
|
Version = "",
|
||||||
|
Dependencies = [],
|
||||||
|
Chunks = [],
|
||||||
|
Strings = [],
|
||||||
|
Functions = [],
|
||||||
|
Resources = [],
|
||||||
|
Sections = [],
|
||||||
|
Ensure = (this,strm,buff,len) =>{
|
||||||
|
if(strm.ReadBlock(buff,0,len) != len)
|
||||||
|
throw $"Could not read {len} byte(s)";
|
||||||
|
},
|
||||||
|
EnsureInt = (this,strm)=>{
|
||||||
|
var buff = ByteArray(4);
|
||||||
|
this.Ensure(strm,buff,4);
|
||||||
|
var number = 0;
|
||||||
|
number |= buff[0] << 24;
|
||||||
|
number |= buff[1] << 16;
|
||||||
|
number |= buff[2] << 8;
|
||||||
|
number |= buff[3];
|
||||||
|
return number;
|
||||||
|
},
|
||||||
|
EnsureString = (this,strm)=>{
|
||||||
|
var len = this.EnsureInt(strm);
|
||||||
|
var buff = ByteArray(len);
|
||||||
|
this.Ensure(strm, buff,len);
|
||||||
|
return buff.ToString();
|
||||||
|
},
|
||||||
|
GetString = (this,strm)=>{
|
||||||
|
var index = this.EnsureInt(strm);
|
||||||
|
if(index < this.Strings.Count) return this.Strings[index];
|
||||||
|
throw $"{index} is not less than {this.Strings.Count}";
|
||||||
|
},
|
||||||
|
Read = (this,stream)=>{
|
||||||
|
var header = ByteArray(8);
|
||||||
|
this.Ensure(stream, header, header.Count);
|
||||||
|
|
||||||
|
var hdrStr = header.ToString();
|
||||||
|
if(hdrStr != "TCROSSVM") throw "Invalid TCrossVM image.";
|
||||||
|
|
||||||
|
this.Ensure(stream, header, 5);
|
||||||
|
|
||||||
|
var version = Tesses.CrossLang.Version.FromBytes(header, 0);
|
||||||
|
|
||||||
|
if(version > Tesses.CrossLang.Version.Current) throw "Runtime is too old.";
|
||||||
|
this.Ensure(stream, header, 5);
|
||||||
|
|
||||||
|
|
||||||
|
this.Version = Tesses.CrossLang.Version.FromBytes(header,0);
|
||||||
|
|
||||||
|
var sec = ByteArray(4);
|
||||||
|
var sectionCount = this.EnsureInt(stream);
|
||||||
|
|
||||||
|
|
||||||
|
for(var i = 0; i < sectionCount; i++)
|
||||||
|
{
|
||||||
|
|
||||||
|
this.Ensure(stream, sec, sec.Count);
|
||||||
|
hdrStr = sec.ToString();
|
||||||
|
var tableLength = this.EnsureInt(stream);
|
||||||
|
if(hdrStr == "NAME")
|
||||||
|
{
|
||||||
|
this.Name = this.GetString(stream);
|
||||||
|
}
|
||||||
|
else if(hdrStr == "INFO")
|
||||||
|
{
|
||||||
|
this.Info = this.GetString(stream);
|
||||||
|
}
|
||||||
|
else if(hdrStr == "DEPS")
|
||||||
|
{
|
||||||
|
var _name = this.GetString(stream);
|
||||||
|
this.Ensure(stream, header, 5);
|
||||||
|
var _version = Tesses.CrossLang.Version.FromBytes(header,0);
|
||||||
|
this.Dependencies.Add({
|
||||||
|
Name = _name,
|
||||||
|
Version = _version
|
||||||
|
});
|
||||||
|
}
|
||||||
|
else if(hdrStr == "RESO")
|
||||||
|
{
|
||||||
|
var resource = ByteArray(tableLength);
|
||||||
|
this.Ensure(stream,resource,resource.Count);
|
||||||
|
this.Resources.Add(resource);
|
||||||
|
}
|
||||||
|
else if(hdrStr == "CHKS")
|
||||||
|
{
|
||||||
|
var chunkCount = this.EnsureInt(stream);
|
||||||
|
for(var j = 0; j < chunkCount; j++)
|
||||||
|
{
|
||||||
|
var _args = [];
|
||||||
|
var _argCount = this.EnsureInt(stream);
|
||||||
|
for(var k = 0; k < _argCount; k++)
|
||||||
|
{
|
||||||
|
_args.Add(this.GetString(stream));
|
||||||
|
}
|
||||||
|
var _code = ByteArray(this.EnsureInt(stream));
|
||||||
|
this.Ensure(stream,_code,_code.Count);
|
||||||
|
var chunk = {
|
||||||
|
Arguments = _args,
|
||||||
|
Code = _code
|
||||||
|
};
|
||||||
|
this.Chunks.Add(chunk);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else if(hdrStr == "FUNS")
|
||||||
|
{
|
||||||
|
var funLen = this.EnsureInt(stream);
|
||||||
|
for(var j = 0; j < funLen; j++)
|
||||||
|
{
|
||||||
|
var fnPartsCount = this.EnsureInt(stream);
|
||||||
|
var documentation = "";
|
||||||
|
var fnParts = [];
|
||||||
|
for(var k = 0; k < fnPartsCount; k++)
|
||||||
|
{
|
||||||
|
if(k == 0) documentation = this.GetString(stream);
|
||||||
|
else fnParts.Add(this.GetString(stream));
|
||||||
|
}
|
||||||
|
var fnId = this.EnsureInt(stream);
|
||||||
|
this.Functions.Add({
|
||||||
|
Documentation=documentation,
|
||||||
|
FunctionNameParts = fnParts,
|
||||||
|
Closure = fnId
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else if(hdrStr == "STRS")
|
||||||
|
{
|
||||||
|
var strcnt = this.EnsureInt(stream);
|
||||||
|
for(var j = 0; j < strcnt; j++)
|
||||||
|
{
|
||||||
|
this.Strings.Add(this.EnsureString(stream));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
var data = ByteArray(tableLength);
|
||||||
|
this.Ensure(stream,data,data.Count);
|
||||||
|
this.Sections.Add({
|
||||||
|
Name=hdrStr,
|
||||||
|
Data = data
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
}
|
|
@ -0,0 +1,103 @@
|
||||||
|
func Tesses.CrossLang.Version.Create(major,minor,patch,build,stage)
|
||||||
|
{
|
||||||
|
return {
|
||||||
|
Major = major,
|
||||||
|
Minor = minor,
|
||||||
|
Patch = patch,
|
||||||
|
Build = build,
|
||||||
|
Stage = stage,
|
||||||
|
getBuildAsInt = (this)=>{
|
||||||
|
return ((this.Build & 0x3FFF) << 2) | ((this.Stage & 0x03));
|
||||||
|
},
|
||||||
|
getVersionInt = (this)=>{
|
||||||
|
return ((this.Major & 0xFF) << 32) | ((this.Minor & 0xFF) << 24)
|
||||||
|
| ((this.Patch & 0xFF) << 16) | (this.BuildAsInt & 0xFFFF);
|
||||||
|
},
|
||||||
|
operator< = (this,right)=>{
|
||||||
|
return this.VersionInt < right.VersionInt;
|
||||||
|
},
|
||||||
|
operator> = (this,right)=>{
|
||||||
|
return this.VersionInt > right.VersionInt;
|
||||||
|
},
|
||||||
|
operator== = (this,right)=>{
|
||||||
|
return this.VersionInt == right.VersionInt;
|
||||||
|
},
|
||||||
|
operator<= = (this,right)=>{
|
||||||
|
return this.VersionInt <= right.VersionInt;
|
||||||
|
},
|
||||||
|
operator>= = (this,right)=>{
|
||||||
|
return this.VersionInt >= right.VersionInt;
|
||||||
|
},
|
||||||
|
operator!= = (this,right)=>{
|
||||||
|
return this.VersionInt != right.VersionInt;
|
||||||
|
},
|
||||||
|
ToString = (this) => {
|
||||||
|
var stage = this.Stage == 0 ? "dev" : this.Stage == 1 ? "alpha" : this.Stage == 2 ? "beta" : "prod";
|
||||||
|
return $"{this.Major & 0xFF}.{this.Minor & 0xFF}.{this.Patch & 0xFF}.{this.Build & 0x3FFF}-{stage}";
|
||||||
|
},
|
||||||
|
ToBytes = (this, buff, off) => {
|
||||||
|
if((buff.Count - offset) < 5) throw "Not long enough";
|
||||||
|
buff[off] = this.Major;
|
||||||
|
buff[off+1] = this.Minor;
|
||||||
|
buff[off+2] = this.Patch;
|
||||||
|
var b = this.BuildAsInt;
|
||||||
|
buff[off+3] = (b >> 8) & 0xFF;
|
||||||
|
buff[off+4] = b & 0xFF;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
}
|
||||||
|
func Tesses.CrossLang.Version.FromBytes(buffer, offset)
|
||||||
|
{
|
||||||
|
|
||||||
|
if((buffer.Count - offset) < 5) throw "Not long enough";
|
||||||
|
|
||||||
|
var major = buffer[offset];
|
||||||
|
var minor = buffer[offset+1];
|
||||||
|
var patch = buffer[offset+2];
|
||||||
|
|
||||||
|
var buildI = (buffer[offset+3] << 8) | (buffer[offset+4]);
|
||||||
|
|
||||||
|
var build = (buildI >> 2);
|
||||||
|
|
||||||
|
|
||||||
|
var stage = buildI & 0x03;
|
||||||
|
|
||||||
|
var b = Tesses.CrossLang.Version.Create(major,minor,patch,build,stage);
|
||||||
|
return b;
|
||||||
|
}
|
||||||
|
func Tesses.CrossLang.Version.CreateEmpty()
|
||||||
|
{
|
||||||
|
return Tesses.CrossLang.Version.Create(1,0,0,0,Tesses.CrossLang.Version.Prod);
|
||||||
|
}
|
||||||
|
func Tesses.CrossLang.Version.Parse(ver)
|
||||||
|
{
|
||||||
|
var mySplit = ver.Split("-",false,2);
|
||||||
|
var version = 3;
|
||||||
|
if(mySplit.Count >= 1)
|
||||||
|
{
|
||||||
|
if(mySplit.Count == 2)
|
||||||
|
{
|
||||||
|
if(mySplit[1] == "dev") version = 0;
|
||||||
|
else if(mySplit[1] == "alpha") version = 1;
|
||||||
|
else if(mySplit[2] == "beta") version = 2;
|
||||||
|
}
|
||||||
|
var vpart = mySplit[0].Split(".",false,4);
|
||||||
|
var major = 1;
|
||||||
|
var minor = 0;
|
||||||
|
var patch = 0;
|
||||||
|
var build = 0;
|
||||||
|
|
||||||
|
if(vpart.Count >= 1) major = ParseLong(vpart[0]); if(TypeOf(major) != "Long") major = 1;
|
||||||
|
if(vpart.Count >= 2) minor = ParseLong(vpart[1]); if(TypeOf(minor) != "Long") minor = 0;
|
||||||
|
if(vpart.Count >= 3) patch = ParseLong(vpart[2]); if(TypeOf(patch) != "Long") patch = 0;
|
||||||
|
if(vpart.Count >= 4) build = ParseLong(vpart[3]); if(TypeOf(build) != "Long") build = 0;
|
||||||
|
|
||||||
|
return Tesses.CrossLang.Version.Create(major,minor,patch,build,version);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
Tesses.CrossLang.Version.Dev = 0;
|
||||||
|
Tesses.CrossLang.Version.Alpha = 1;
|
||||||
|
Tesses.CrossLang.Version.Beta = 2;
|
||||||
|
Tesses.CrossLang.Version.Prod = 3;
|
||||||
|
|
||||||
|
Tesses.CrossLang.Version.Current = Tesses.CrossLang.Version.Create(1,0,0,0,Tesses.CrossLang.Version.Prod);
|
|
@ -0,0 +1,11 @@
|
||||||
|
{
|
||||||
|
"name": "Tesses.CrossLang.Markup",
|
||||||
|
"version": "1.0.0.0-prod",
|
||||||
|
"info": {
|
||||||
|
"maintainer": "Mike Nolan",
|
||||||
|
"type": "compile_tool",
|
||||||
|
"repo": "https://gitea.site.tesses.net/tesses50/crosslang/crosslang-libs",
|
||||||
|
"homepage": "https://crosslang.tesseslanguage.com/",
|
||||||
|
"license": "LGPLv3"
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,818 @@
|
||||||
|
func crossmarkuplexer(data)
|
||||||
|
{
|
||||||
|
var tokens = [];
|
||||||
|
var i = 0;
|
||||||
|
var peeked=null;
|
||||||
|
var inSpecial=false;
|
||||||
|
|
||||||
|
var builder = "";
|
||||||
|
func read()
|
||||||
|
{
|
||||||
|
if(peeked)
|
||||||
|
{
|
||||||
|
var myPeeked=peeked;
|
||||||
|
peeked = null;
|
||||||
|
return myPeeked;
|
||||||
|
}
|
||||||
|
if(i < data.Length) {
|
||||||
|
var rc = data[i++];
|
||||||
|
return rc;
|
||||||
|
}
|
||||||
|
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
func peek()
|
||||||
|
{
|
||||||
|
if(peeked) return peeked;
|
||||||
|
peeked = read();
|
||||||
|
return peeked;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
func flush()
|
||||||
|
{
|
||||||
|
if(builder.Count > 0)
|
||||||
|
{
|
||||||
|
tokens.Add({
|
||||||
|
Type = inSpecial ? "Identifier" : "Text",
|
||||||
|
Text = builder
|
||||||
|
});
|
||||||
|
builder = "";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func ReadChar()
|
||||||
|
{
|
||||||
|
var r2 = read();
|
||||||
|
|
||||||
|
if(!r2) return null;
|
||||||
|
if(r2 == '\\')
|
||||||
|
{
|
||||||
|
r2 = read();
|
||||||
|
if(!r2)
|
||||||
|
{
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
return $"\\{r2}";
|
||||||
|
}
|
||||||
|
|
||||||
|
return r2.ToString();
|
||||||
|
}
|
||||||
|
|
||||||
|
func ReadString()
|
||||||
|
{
|
||||||
|
var str = "";
|
||||||
|
while(var myChar = ReadChar())
|
||||||
|
{
|
||||||
|
if(myChar == "\"") break;
|
||||||
|
str += myChar;
|
||||||
|
}
|
||||||
|
return str;
|
||||||
|
}
|
||||||
|
|
||||||
|
while(r = read())
|
||||||
|
{
|
||||||
|
var p = peek();
|
||||||
|
if(!inSpecial && r == '<')
|
||||||
|
{
|
||||||
|
if(p == '?')
|
||||||
|
{
|
||||||
|
read();
|
||||||
|
|
||||||
|
|
||||||
|
flush();
|
||||||
|
|
||||||
|
tokens.Add({
|
||||||
|
Type = "EnterSpecial"
|
||||||
|
});
|
||||||
|
|
||||||
|
|
||||||
|
inSpecial=true;
|
||||||
|
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
builder += "<";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else if(inSpecial && (r == '\r' || r == '\n' || r == ' ' || r == '\t'))
|
||||||
|
{
|
||||||
|
flush();
|
||||||
|
}
|
||||||
|
else if(inSpecial && r == '\"')
|
||||||
|
{
|
||||||
|
flush();
|
||||||
|
var myStr = ReadString();
|
||||||
|
tokens.Add({
|
||||||
|
Type = "String",
|
||||||
|
Text = myStr
|
||||||
|
});
|
||||||
|
}
|
||||||
|
else if(inSpecial && r == '\'')
|
||||||
|
{
|
||||||
|
flush();
|
||||||
|
var myChr = ReadChar();
|
||||||
|
tokens.Add({
|
||||||
|
Type = "Char",
|
||||||
|
Text = myChr
|
||||||
|
});
|
||||||
|
read();
|
||||||
|
}
|
||||||
|
else if(inSpecial && r == '=')
|
||||||
|
{
|
||||||
|
flush();
|
||||||
|
tokens.Add({
|
||||||
|
Type = "Equals"
|
||||||
|
});
|
||||||
|
}
|
||||||
|
else if(inSpecial && r == '(')
|
||||||
|
{
|
||||||
|
flush();
|
||||||
|
tokens.Add({
|
||||||
|
Type = "OpenParen"
|
||||||
|
});
|
||||||
|
}
|
||||||
|
else if(inSpecial && r == ')')
|
||||||
|
{
|
||||||
|
flush();
|
||||||
|
tokens.Add({
|
||||||
|
Type = "CloseParen"
|
||||||
|
});
|
||||||
|
}
|
||||||
|
else if(inSpecial && r == ',')
|
||||||
|
{
|
||||||
|
flush();
|
||||||
|
tokens.Add({
|
||||||
|
Type = "Comma"
|
||||||
|
});
|
||||||
|
}
|
||||||
|
else if(inSpecial && r == '?')
|
||||||
|
{
|
||||||
|
if(p == '?')
|
||||||
|
{
|
||||||
|
read();
|
||||||
|
builder += "?";
|
||||||
|
}
|
||||||
|
else if(p == '>')
|
||||||
|
{
|
||||||
|
read();
|
||||||
|
|
||||||
|
flush();
|
||||||
|
tokens.Add({
|
||||||
|
Type = "ExitSpecial"
|
||||||
|
});
|
||||||
|
inSpecial=false;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
builder += read().ToString();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
builder += r.ToString();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
flush();
|
||||||
|
|
||||||
|
return tokens;
|
||||||
|
}
|
||||||
|
|
||||||
|
func crossmarkupparser(tokens)
|
||||||
|
{
|
||||||
|
var i = 0;
|
||||||
|
|
||||||
|
func NotEnd()
|
||||||
|
{
|
||||||
|
if(i + 3 > tokens.Count) return false;
|
||||||
|
|
||||||
|
if(tokens[i].Type != "EnterSpecial")
|
||||||
|
return true;
|
||||||
|
|
||||||
|
if(tokens[i+1].Type != "Identifier")
|
||||||
|
return true;
|
||||||
|
if(tokens[i+1].Text != "end")
|
||||||
|
return true;
|
||||||
|
if(tokens[i+2].Type != "ExitSpecial")
|
||||||
|
return true;
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
func EnsureEnd()
|
||||||
|
{
|
||||||
|
if(NotEnd())
|
||||||
|
{
|
||||||
|
throw "Must end with <?end?>";
|
||||||
|
}
|
||||||
|
i += 3;
|
||||||
|
}
|
||||||
|
|
||||||
|
func TokenTypeIs(type)
|
||||||
|
{
|
||||||
|
return i < tokens.Length && tokens[i].Type == type;
|
||||||
|
}
|
||||||
|
|
||||||
|
func EnsureTokenType(type)
|
||||||
|
{
|
||||||
|
if(!TokenTypeIs(type))
|
||||||
|
{
|
||||||
|
throw $"The token is {type} which is not {tokens[i].Type}";
|
||||||
|
}
|
||||||
|
i++;
|
||||||
|
}
|
||||||
|
|
||||||
|
func ConsumeIfTokenTypeIs(type)
|
||||||
|
{
|
||||||
|
if(TokenTypeIs(type)) i++;
|
||||||
|
}
|
||||||
|
|
||||||
|
func parse_node()
|
||||||
|
{
|
||||||
|
if(i < tokens.Length)
|
||||||
|
{
|
||||||
|
var myToken = tokens[i++];
|
||||||
|
if(myToken.Type == "EnterSpecial")
|
||||||
|
{
|
||||||
|
if(i < tokens.Length)
|
||||||
|
{
|
||||||
|
var myToken2 = tokens[i++];
|
||||||
|
if(myToken2.Type == "Identifier")
|
||||||
|
{
|
||||||
|
if(myToken2.Text == "page")
|
||||||
|
{
|
||||||
|
var pageargs = [];
|
||||||
|
var nodes =[];
|
||||||
|
var route = "/";
|
||||||
|
var router_function = "Router";
|
||||||
|
//its a page
|
||||||
|
|
||||||
|
EnsureTokenType("OpenParen");
|
||||||
|
while(!TokenTypeIs("CloseParen"))
|
||||||
|
{
|
||||||
|
|
||||||
|
ConsumeIfTokenTypeIs("Comma");
|
||||||
|
if(i < tokens.Length && tokens[i].Type == "Identifier")
|
||||||
|
{
|
||||||
|
pageargs.Add(tokens[i].Text);
|
||||||
|
i++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
EnsureTokenType("CloseParen");
|
||||||
|
|
||||||
|
while(!TokenTypeIs("ExitSpecial"))
|
||||||
|
{
|
||||||
|
if(TokenTypeIs("Identifier"))
|
||||||
|
{
|
||||||
|
var key = tokens[i++].Text;
|
||||||
|
EnsureTokenType("Equals");
|
||||||
|
if(TokenTypeIs("String"))
|
||||||
|
{
|
||||||
|
var value = tokens[i++].Text;
|
||||||
|
if(key == "route")
|
||||||
|
route = value;
|
||||||
|
else if(key == "router_function")
|
||||||
|
router_function = value;
|
||||||
|
else
|
||||||
|
throw $"Unknown property {key}";
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
throw "Not a string";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
throw "Not an identifier";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
EnsureTokenType("ExitSpecial");
|
||||||
|
while(NotEnd())
|
||||||
|
{
|
||||||
|
nodes.Add(parse_node());
|
||||||
|
}
|
||||||
|
EnsureEnd();
|
||||||
|
|
||||||
|
|
||||||
|
return {
|
||||||
|
|
||||||
|
Type = "PageNode",
|
||||||
|
Arguments = pageargs,
|
||||||
|
Route = route,
|
||||||
|
RouterFunction = router_function,
|
||||||
|
Nodes = nodes
|
||||||
|
};
|
||||||
|
}
|
||||||
|
else if(myToken2.Text == "component")
|
||||||
|
{
|
||||||
|
var pageargs = [];
|
||||||
|
var nodes =[];
|
||||||
|
var name = "Component";
|
||||||
|
//its a component
|
||||||
|
|
||||||
|
EnsureTokenType("OpenParen");
|
||||||
|
while(!TokenTypeIs("CloseParen"))
|
||||||
|
{
|
||||||
|
|
||||||
|
ConsumeIfTokenTypeIs("Comma");
|
||||||
|
if(i < tokens.Length && tokens[i].Type == "Identifier")
|
||||||
|
{
|
||||||
|
pageargs.Add(tokens[i].Text);
|
||||||
|
i++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
EnsureTokenType("CloseParen");
|
||||||
|
|
||||||
|
while(!TokenTypeIs("ExitSpecial"))
|
||||||
|
{
|
||||||
|
if(TokenTypeIs("Identifier"))
|
||||||
|
{
|
||||||
|
var key = tokens[i++].Text;
|
||||||
|
EnsureTokenType("Equals");
|
||||||
|
if(TokenTypeIs("String"))
|
||||||
|
{
|
||||||
|
var value = tokens[i++].Text;
|
||||||
|
if(key == "name")
|
||||||
|
name = value;
|
||||||
|
else
|
||||||
|
throw $"Unknown property {key}";
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
throw "Not a string";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
throw "Not an identifier";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
EnsureTokenType("ExitSpecial");
|
||||||
|
while(NotEnd())
|
||||||
|
{
|
||||||
|
nodes.Add(parse_node());
|
||||||
|
}
|
||||||
|
EnsureEnd();
|
||||||
|
|
||||||
|
|
||||||
|
return {
|
||||||
|
|
||||||
|
Type = "ComponentNode",
|
||||||
|
Arguments = pageargs,
|
||||||
|
Name = name,
|
||||||
|
Nodes = nodes
|
||||||
|
};
|
||||||
|
}
|
||||||
|
else if(myToken2.Text == "code")
|
||||||
|
{
|
||||||
|
var nodes = [];
|
||||||
|
while(!TokenTypeIs("ExitSpecial"))
|
||||||
|
{
|
||||||
|
if(i < tokens.Length)
|
||||||
|
nodes.Add(parse_node());
|
||||||
|
}
|
||||||
|
EnsureTokenType("ExitSpecial");
|
||||||
|
return {
|
||||||
|
Type = "CodeNode",
|
||||||
|
Nodes = nodes
|
||||||
|
};
|
||||||
|
}
|
||||||
|
else if(myToken2.Text == "resource")
|
||||||
|
{
|
||||||
|
var name = "";
|
||||||
|
var route = "";
|
||||||
|
var router_function = "Router";
|
||||||
|
while(!TokenTypeIs("ExitSpecial"))
|
||||||
|
{
|
||||||
|
if(TokenTypeIs("Identifier"))
|
||||||
|
{
|
||||||
|
var key = tokens[i++].Text;
|
||||||
|
EnsureTokenType("Equals");
|
||||||
|
if(TokenTypeIs("String"))
|
||||||
|
{
|
||||||
|
var value = tokens[i++].Text;
|
||||||
|
if(key == "name")
|
||||||
|
name = value;
|
||||||
|
else if(key == "route")
|
||||||
|
route = value;
|
||||||
|
else if(key == "router_function")
|
||||||
|
router_function = value;
|
||||||
|
else
|
||||||
|
throw $"Unknown property {key}";
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
throw "Not a string";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
throw "Not an identifier";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
EnsureTokenType("ExitSpecial");
|
||||||
|
return {
|
||||||
|
Type = "EmbedNode",
|
||||||
|
Name = name,
|
||||||
|
Route = route,
|
||||||
|
RouterFunction = router_function
|
||||||
|
};
|
||||||
|
}
|
||||||
|
else if(myToken2.Text == "expr")
|
||||||
|
{
|
||||||
|
var nodes = [];
|
||||||
|
while(!TokenTypeIs("ExitSpecial"))
|
||||||
|
{
|
||||||
|
if(i < tokens.Length)
|
||||||
|
nodes.Add(parse_node());
|
||||||
|
}
|
||||||
|
|
||||||
|
EnsureTokenType("ExitSpecial");
|
||||||
|
return {
|
||||||
|
Type = "ExprNode",
|
||||||
|
Nodes = nodes
|
||||||
|
};
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
EnsureTokenType("ExitSpecial");
|
||||||
|
|
||||||
|
var args = [];
|
||||||
|
|
||||||
|
while(NotEnd())
|
||||||
|
{
|
||||||
|
if(TokenTypeIs("Text"))
|
||||||
|
{
|
||||||
|
EnsureTokenType("Text");
|
||||||
|
}
|
||||||
|
else if(TokenTypeIs("EnterSpecial"))
|
||||||
|
{
|
||||||
|
EnsureTokenType("EnterSpecial");
|
||||||
|
|
||||||
|
var myToken3 = tokens[i++];
|
||||||
|
|
||||||
|
if(myToken3.Type == "Identifier")
|
||||||
|
{
|
||||||
|
if(myToken3.Text == "arg")
|
||||||
|
{
|
||||||
|
var nodes = [];
|
||||||
|
while(!TokenTypeIs("ExitSpecial"))
|
||||||
|
{
|
||||||
|
if(i < tokens.Length)
|
||||||
|
nodes.Add(parse_node());
|
||||||
|
}
|
||||||
|
EnsureTokenType("ExitSpecial");
|
||||||
|
|
||||||
|
args.Add({
|
||||||
|
Type = "ArgNode",
|
||||||
|
Nodes = nodes
|
||||||
|
});
|
||||||
|
}
|
||||||
|
else if(myToken3.Text == "arg_component")
|
||||||
|
{
|
||||||
|
var pageargs = [];
|
||||||
|
var nodes =[];
|
||||||
|
//its a component
|
||||||
|
|
||||||
|
EnsureTokenType("OpenParen");
|
||||||
|
while(!TokenTypeIs("CloseParen"))
|
||||||
|
{
|
||||||
|
|
||||||
|
ConsumeIfTokenTypeIs("Comma");
|
||||||
|
if(i < tokens.Length && tokens[i].Type == "Identifier")
|
||||||
|
{
|
||||||
|
pageargs.Add(tokens[i].Text);
|
||||||
|
i++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
EnsureTokenType("CloseParen");
|
||||||
|
EnsureTokenType("ExitSpecial");
|
||||||
|
while(NotEnd())
|
||||||
|
{
|
||||||
|
nodes.Add(parse_node());
|
||||||
|
}
|
||||||
|
EnsureEnd();
|
||||||
|
|
||||||
|
args.Add({
|
||||||
|
Type = "ArgComponentNode",
|
||||||
|
Arguments = pageargs,
|
||||||
|
Nodes = nodes
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
throw "Must be an identifier";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
EnsureEnd();
|
||||||
|
return {
|
||||||
|
Type = "UseComponentNode",
|
||||||
|
Name = myToken2.Text,
|
||||||
|
Arguments = args
|
||||||
|
};
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else if(myToken.Type == "Identifier")
|
||||||
|
{
|
||||||
|
return {
|
||||||
|
Type = "IdentifierNode",
|
||||||
|
Text = myToken.Text
|
||||||
|
};
|
||||||
|
}
|
||||||
|
else if(myToken.Type == "Text")
|
||||||
|
{
|
||||||
|
return {
|
||||||
|
Type = "TextNode",
|
||||||
|
Text = myToken.Text
|
||||||
|
};
|
||||||
|
}
|
||||||
|
else if(myToken.Type == "Char")
|
||||||
|
{
|
||||||
|
return {
|
||||||
|
Type = "CharNode",
|
||||||
|
Text = $"\'{myToken.Text}\'"
|
||||||
|
};
|
||||||
|
}
|
||||||
|
else if(myToken.Type == "String")
|
||||||
|
{
|
||||||
|
return {
|
||||||
|
Type = "StringNode",
|
||||||
|
Text = $"\"{myToken.Text}\""
|
||||||
|
};
|
||||||
|
}
|
||||||
|
else if(myToken.Type == "Equals" || myToken.Type == "OpenParen" || myToken.Type == "CloseParen" || myToken.Type == "Comma" || myToken.Type == "")
|
||||||
|
{
|
||||||
|
return {
|
||||||
|
Type = $"{myToken.Type}Node"
|
||||||
|
};
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
var nodes = [];
|
||||||
|
|
||||||
|
while(i < tokens.Length)
|
||||||
|
{
|
||||||
|
nodes.Add(parse_node());
|
||||||
|
}
|
||||||
|
return {
|
||||||
|
Type = "RootNode",
|
||||||
|
Nodes = nodes
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
func crossmarkupgen(ast)
|
||||||
|
{
|
||||||
|
var page_functions = [];
|
||||||
|
|
||||||
|
var code = "";
|
||||||
|
|
||||||
|
func add_to_page(name, code)
|
||||||
|
{
|
||||||
|
each(var item : page_functions)
|
||||||
|
{
|
||||||
|
if(item.Key == name)
|
||||||
|
{
|
||||||
|
item.Value += code;
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
page_functions.Add({
|
||||||
|
Key = name,
|
||||||
|
Value = code
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
func generate_node(node)
|
||||||
|
{
|
||||||
|
func myescape(txt)
|
||||||
|
{
|
||||||
|
var out = "";
|
||||||
|
each(var c : txt)
|
||||||
|
{
|
||||||
|
var cI = c.ToLong();
|
||||||
|
if(cI < 32 || cI > 126)
|
||||||
|
{
|
||||||
|
out += $"\\x{(cI % 0xFF).ToHexString(2)}";
|
||||||
|
}
|
||||||
|
else if(c == '\"')
|
||||||
|
{
|
||||||
|
out += "\\\"";
|
||||||
|
}
|
||||||
|
else if(c == '\'')
|
||||||
|
{
|
||||||
|
out += "\\\'";
|
||||||
|
}
|
||||||
|
else if(c == '\\')
|
||||||
|
{
|
||||||
|
out += "\\\\";
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
out += c;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return out;
|
||||||
|
}
|
||||||
|
if(node.Type == "PageNode")
|
||||||
|
{
|
||||||
|
var code = $"if(ctx.Path == \"{node.Route}\")";
|
||||||
|
code += "{__writer = ctx.OpenResponseStream(); ";
|
||||||
|
each(var a : node.Arguments)
|
||||||
|
{
|
||||||
|
code += $"var {a} = ctx.QueryParams.TryGetFirst(\"{a}\");";
|
||||||
|
}
|
||||||
|
each(var item : node.Nodes)
|
||||||
|
{
|
||||||
|
code += generate_node(item);
|
||||||
|
}
|
||||||
|
code += " __writer.Close(); return true;}";
|
||||||
|
|
||||||
|
add_to_page(node.RouterFunction,code);
|
||||||
|
return "";
|
||||||
|
}
|
||||||
|
else if(node.Type == "EmbedNode")
|
||||||
|
{
|
||||||
|
var code = $"if(ctx.Path == \"{node.Route}\")";
|
||||||
|
code += "{";
|
||||||
|
code += $"ctx.WithMimeType(Net.Http.MimeType(\"{node.Name}\")).SendBytes(embed(\"{node.Name}\"));";
|
||||||
|
code += "return true;";
|
||||||
|
code += "}";
|
||||||
|
}
|
||||||
|
else if(node.Type == "TextNode")
|
||||||
|
{
|
||||||
|
return $"write(\"{myescape(node.Text)}\");";
|
||||||
|
}
|
||||||
|
else if(node.Type == "ExprNode")
|
||||||
|
{
|
||||||
|
var code = "write(";
|
||||||
|
each(var item : node.Nodes)
|
||||||
|
{
|
||||||
|
code += generate_node(item);
|
||||||
|
}
|
||||||
|
code += ");";
|
||||||
|
return code;
|
||||||
|
}
|
||||||
|
else if(node.Type == "CodeNode")
|
||||||
|
{
|
||||||
|
var code = "";
|
||||||
|
each(var item : node.Nodes)
|
||||||
|
{
|
||||||
|
code += generate_node(item);
|
||||||
|
}
|
||||||
|
return code;
|
||||||
|
}
|
||||||
|
else if(node.Type == "ComponentNode")
|
||||||
|
{
|
||||||
|
var code = $"func {node.Name}(write,ctx";
|
||||||
|
|
||||||
|
each(var arg0 : node.Arguments)
|
||||||
|
{
|
||||||
|
code += $",{arg0}";
|
||||||
|
}
|
||||||
|
code += "){";
|
||||||
|
each(var n : node.Nodes)
|
||||||
|
{
|
||||||
|
code += generate_node(n);
|
||||||
|
}
|
||||||
|
code += "}";
|
||||||
|
return code;
|
||||||
|
}
|
||||||
|
else if(node.Type == "UseComponentNode")
|
||||||
|
{
|
||||||
|
var code = $"{node.Name}(write,ctx";
|
||||||
|
each(var arg : node.Arguments)
|
||||||
|
{
|
||||||
|
code += ",";
|
||||||
|
if(arg.Type == "ArgNode")
|
||||||
|
{
|
||||||
|
each(var itm : arg.Nodes)
|
||||||
|
{
|
||||||
|
code += generate_node(itm);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else if(arg.Type == "ArgComponentNode")
|
||||||
|
{
|
||||||
|
code += "(write,ctx";
|
||||||
|
|
||||||
|
each(var arg0 : arg.Arguments)
|
||||||
|
{
|
||||||
|
code += $",{arg0}";
|
||||||
|
}
|
||||||
|
code += ")=>{";
|
||||||
|
each(var n : arg.Nodes)
|
||||||
|
{
|
||||||
|
code += generate_node(n);
|
||||||
|
}
|
||||||
|
code += "}";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
code += ");";
|
||||||
|
return code;
|
||||||
|
}
|
||||||
|
else if(node.Type == "CharNode")
|
||||||
|
{
|
||||||
|
return $" {node.Text} ";
|
||||||
|
}
|
||||||
|
else if(node.Type == "StringNode")
|
||||||
|
{
|
||||||
|
return $" {node.Text} ";
|
||||||
|
}
|
||||||
|
else if(node.Type == "IdentifierNode")
|
||||||
|
{
|
||||||
|
return $" {node.Text} ";
|
||||||
|
}
|
||||||
|
else if(node.Type == "OpenParenNode")
|
||||||
|
{
|
||||||
|
return " ( ";
|
||||||
|
}
|
||||||
|
else if(node.Type == "CloseParenNode")
|
||||||
|
{
|
||||||
|
return " ) ";
|
||||||
|
}
|
||||||
|
else if(node.Type == "CommaNode")
|
||||||
|
{
|
||||||
|
return " , ";
|
||||||
|
}
|
||||||
|
else if(node.Type == "EqualsNode")
|
||||||
|
{
|
||||||
|
return " = ";
|
||||||
|
}
|
||||||
|
else if(node.Type == "RootNode")
|
||||||
|
{
|
||||||
|
var code = "";
|
||||||
|
|
||||||
|
each(var item : node.Nodes)
|
||||||
|
{
|
||||||
|
if(item.Type != "TextNode")
|
||||||
|
code += generate_node(item);
|
||||||
|
}
|
||||||
|
|
||||||
|
each(var pg : page_functions)
|
||||||
|
{
|
||||||
|
code += $"func {pg.Key}(ctx)";
|
||||||
|
code += "{ ctx.WithMimeType(\"text/html\");";
|
||||||
|
code += "var __writer = null;";
|
||||||
|
|
||||||
|
code += "func write(__text){ __writer.WriteText(__text); }";
|
||||||
|
|
||||||
|
code += pg.Value;
|
||||||
|
|
||||||
|
code += "__writer.Close(); return false;}";
|
||||||
|
}
|
||||||
|
|
||||||
|
return code;
|
||||||
|
}
|
||||||
|
|
||||||
|
return "";
|
||||||
|
}
|
||||||
|
|
||||||
|
return generate_node(ast);
|
||||||
|
}
|
||||||
|
|
||||||
|
func EnumerateFiles(cfg,path)
|
||||||
|
{
|
||||||
|
var txt = "";
|
||||||
|
if(cfg.Project.DirectoryExists(path))
|
||||||
|
each(var file : cfg.Project.EnumeratePaths(path))
|
||||||
|
{
|
||||||
|
if(cfg.Project.RegularFileExists(file))
|
||||||
|
{
|
||||||
|
var f = cfg.Project.OpenFile(file, "rb");
|
||||||
|
var ms = FS.MemoryStream(true);
|
||||||
|
f.CopyTo(ms);
|
||||||
|
txt += ms.GetBytes().ToString();
|
||||||
|
f.Close();
|
||||||
|
ms.Close();
|
||||||
|
}
|
||||||
|
else if(cfg.Project.DirectoryExists(file))
|
||||||
|
{
|
||||||
|
EnumerateFiles(cfg, file);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return txt;
|
||||||
|
}
|
||||||
|
|
||||||
|
func RunTool(cfg)
|
||||||
|
{
|
||||||
|
var text = "";
|
||||||
|
text += EnumerateFiles(cfg, "/components");
|
||||||
|
text += EnumerateFiles(cfg, "/pages");
|
||||||
|
var c = crossmarkuplexer(text);
|
||||||
|
|
||||||
|
var r = crossmarkupparser(c);
|
||||||
|
|
||||||
|
var src = crossmarkupgen(r);
|
||||||
|
|
||||||
|
cfg.GeneratedSource.Add({Source = src, FileName="markup.tcross"});
|
||||||
|
}
|
|
@ -0,0 +1,10 @@
|
||||||
|
{
|
||||||
|
"name": "Tesses.CrossLang.PackageServer",
|
||||||
|
"version": "1.0.0.0-prod",
|
||||||
|
"project_dependencies": [
|
||||||
|
"./Tesses.CrossLang.Markup"
|
||||||
|
],
|
||||||
|
"info": {
|
||||||
|
"type": "console"
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,3 @@
|
||||||
|
<?page() route="/" ?>
|
||||||
|
<h1>Welcome to the package server</h1>
|
||||||
|
<?end?>
|
|
@ -0,0 +1,4 @@
|
||||||
|
func main(args)
|
||||||
|
{
|
||||||
|
Net.Http.ListenSimpleWithLoop(Router,4200);
|
||||||
|
}
|
|
@ -0,0 +1,14 @@
|
||||||
|
{
|
||||||
|
"name": "Tesses.CrossLang.Shell",
|
||||||
|
"version": "1.0.0.0-prod",
|
||||||
|
"info": {
|
||||||
|
"maintainer": "Mike Nolan",
|
||||||
|
"type": "console",
|
||||||
|
"repo": "https://gitea.site.tesses.net/tesses50/crosslang/crosslang-libs",
|
||||||
|
"homepage": "https://crosslang.tesseslanguage.com/",
|
||||||
|
"license": "LGPLv3"
|
||||||
|
},
|
||||||
|
"project_dependencies": [
|
||||||
|
"./Tesses.CrossLang.BuildEssentials"
|
||||||
|
]
|
||||||
|
}
|
|
@ -0,0 +1,4 @@
|
||||||
|
func main(args)
|
||||||
|
{
|
||||||
|
Console.WriteLine("Hello, world");
|
||||||
|
}
|
|
@ -0,0 +1 @@
|
||||||
|
#!/bin/bash
|
|
@ -0,0 +1,48 @@
|
||||||
|
using System;
|
||||||
|
using System.IO;
|
||||||
|
using Newtonsoft.Json;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
namespace Tesses.CrossLang
|
||||||
|
{
|
||||||
|
public class ProjectFile
|
||||||
|
{
|
||||||
|
public string name {get;set;}="";
|
||||||
|
public string version {get;set;}="";
|
||||||
|
|
||||||
|
public string resource_directory {get;set;}="res"; //defaults to res, this is the resource directory used for embed("filename"))
|
||||||
|
|
||||||
|
|
||||||
|
public string source_directory {get;set;}="src"; //defaults to src, used for storing sourcecode
|
||||||
|
|
||||||
|
public string bin_directory {get;set;}="bin"; //defaults to bin, used for storing output
|
||||||
|
|
||||||
|
public string obj_directory {get;set;}="obj"; //defaults to obj, used for storing compile tools
|
||||||
|
|
||||||
|
public List<string> project_dependencies {get;set;}=new List<string>();
|
||||||
|
|
||||||
|
public List<Dependency> dependencies {get;set;}=new List<Dependency>();
|
||||||
|
|
||||||
|
public ProjectInfo info {get;set;}=new ProjectInfo();
|
||||||
|
}
|
||||||
|
public class Dependency {
|
||||||
|
public string name {get;set;}="";
|
||||||
|
|
||||||
|
public string version {get;set;}="";
|
||||||
|
}
|
||||||
|
public class ProjectInfo //this is stored in crvm file as JSON in INFO as well (with index in STRS table)
|
||||||
|
{
|
||||||
|
public string maintainer {get;set;}=""; //Not checked when building project
|
||||||
|
public string type {get;set;}=""; //gets checked whether it is compile_tool by build tool, possible values are in file: project_types.txt
|
||||||
|
public string repo {get;set;}=""; //optional, is the place where the code is stored
|
||||||
|
public string homepage {get;set;}=""; //optional, is the website for the project
|
||||||
|
|
||||||
|
public string license {get;set;}=""; //optional, but recommended to tell people what the license is
|
||||||
|
|
||||||
|
public string readme {get;set;}=""; //optional but tells people about the package
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void Main(string[] args)
|
||||||
|
{
|
||||||
|
var project = JsonConvert.DeserializeObject<ProjectFile>(File.ReadAllText("config.json"));
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,6 @@
|
||||||
|
console: a console application (or webserver)
|
||||||
|
lib: a library
|
||||||
|
app: a gui app (used for eventual gui system)
|
||||||
|
template: used for project templates
|
||||||
|
compile_tool: run before source is compiled for project if it is in the dependency tree for the project (and is not linked to said projects)
|
||||||
|
tool: a tool invokable via crosslang
|
|
@ -0,0 +1,3 @@
|
||||||
|
#!/bin/bash
|
||||||
|
cd Tesses.CrossLang.BuildEssentials && crossc -o ./bin-tmp -n Tesses.CrossLang.BuildEssentials -v 1.0.0.0-prod main.tcross src/*.tcross && cd ..
|
||||||
|
crossvm ./Tesses.CrossLang.BuildEssentials/bin-tmp/Tesses.CrossLang.BuildEssentials-1.0.0.0-prod.crvm Tesses.CrossLang.Shell
|
Loading…
Reference in New Issue