mirror of
https://onedev.site.tesses.net/crosslang/crosslang-website
synced 2026-02-08 09:05:47 +00:00
First commit
This commit is contained in:
2
.gitignore
vendored
Normal file
2
.gitignore
vendored
Normal file
@@ -0,0 +1,2 @@
|
||||
public
|
||||
.hugo_build.lock
|
||||
3
.gitmodules
vendored
Normal file
3
.gitmodules
vendored
Normal file
@@ -0,0 +1,3 @@
|
||||
[submodule "themes/hugo-theme-relearn"]
|
||||
path = themes/hugo-theme-relearn
|
||||
url = https://github.com/McShelby/hugo-theme-relearn.git
|
||||
5
archetypes/default.md
Normal file
5
archetypes/default.md
Normal file
@@ -0,0 +1,5 @@
|
||||
+++
|
||||
title = '{{ replace .File.ContentBaseName "-" " " | title }}'
|
||||
date = {{ .Date }}
|
||||
draft = true
|
||||
+++
|
||||
26
content/_index.md
Normal file
26
content/_index.md
Normal file
@@ -0,0 +1,26 @@
|
||||
+++
|
||||
title = "CrossLang"
|
||||
type = "home"
|
||||
+++
|
||||
|
||||
> :warning: **NOT READY FOR PRODUCTION (THERE WILL BE BREAKING CHANGES)**
|
||||
|
||||
My dynamic programming language
|
||||
|
||||
## Essential Links
|
||||
|
||||
- [Linux](https://crosslang.tesseslanguage.com/download/crosslang-x86_64.tar.gz)
|
||||
- [Windows](https://crosslang.tesseslanguage.com/download/crosslang-win32.exe)
|
||||
- [Windows Portable](https://crosslang.tesseslanguage.com/download/crosslang-win32.zip)
|
||||
- [ISO](https://crosslang.tesseslanguage.com/download/crosslang.iso)
|
||||
- [More Binaries](https://crosslang.tesseslanguage.com/download/)
|
||||
- [Packages](https://cpkg.tesseslanguage.com/)
|
||||
- [Source](https://onedev.site.tesses.net/crosslang)
|
||||
|
||||
|
||||
```
|
||||
Ye are of God, little children, and have overcome them: because greater is he that is in you, than he that is in the world. (1 John 4:4)
|
||||
```
|
||||
|
||||
|
||||
Language License is [GPLv3](https://onedev.site.tesses.net/crosslang/~files/master/LICENSE.md)
|
||||
7
content/language-features/_index.md
Normal file
7
content/language-features/_index.md
Normal file
@@ -0,0 +1,7 @@
|
||||
+++
|
||||
title = "Language Features"
|
||||
type = "chapter"
|
||||
weight = 2
|
||||
+++
|
||||
|
||||
- [The basics](basics.md)
|
||||
585
content/language-features/basics.md
Normal file
585
content/language-features/basics.md
Normal file
@@ -0,0 +1,585 @@
|
||||
+++
|
||||
title = 'The basics'
|
||||
date = 2025-05-08T22:23:44-05:00
|
||||
+++
|
||||
|
||||
This is a book for my language found [here](https://crosslang.tesseslanguage.com/)
|
||||
|
||||
|
||||
|
||||
## Statements and loops
|
||||
|
||||
|
||||
|
||||
#### Declare a variable (it is an expression)
|
||||
|
||||
You can (the var is optional but should be used if the root environment has the same variable and you don't want to set it)
|
||||
|
||||
```js
|
||||
var myVariable = 42;
|
||||
```
|
||||
|
||||
#### Set a variable (it is an expression)
|
||||
|
||||
```js
|
||||
myVariable = "I have set the variable to a string";
|
||||
```
|
||||
|
||||
#### If statements
|
||||
|
||||
The {} are optional if you only need one statement
|
||||
|
||||
```js
|
||||
var myExpression = 0;
|
||||
var myOtherExpression = {
|
||||
mol = 42
|
||||
};
|
||||
|
||||
if(myExpression)
|
||||
{
|
||||
Console.WriteLine("myExpression is truthy");
|
||||
}
|
||||
else if(myOtherExpression)
|
||||
{
|
||||
//this will run based on the condition
|
||||
Console.WriteLine("myExpression is falsey but myOtherExpression is truthy");
|
||||
}
|
||||
else {
|
||||
Console.WriteLine("both myExpression and myOtherExpression are falsey");
|
||||
}
|
||||
```
|
||||
|
||||
#### For loop
|
||||
|
||||
Note: i will leak, also you can use curly brackets like if
|
||||
|
||||
```js
|
||||
for(var i = 0; i < 42; i++)
|
||||
Console.WriteLine(i);
|
||||
```
|
||||
|
||||
#### Each loop
|
||||
|
||||
```js
|
||||
enumerable MyItterator()
|
||||
{
|
||||
yield 42;
|
||||
yield 100;
|
||||
yield 88;
|
||||
}
|
||||
each(var item : MyItterator())
|
||||
{
|
||||
Console.WriteLine(item);
|
||||
}
|
||||
|
||||
|
||||
each(var item : [3,7,12])
|
||||
{
|
||||
Console.WriteLine(item);
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
This should output
|
||||
42
|
||||
100
|
||||
88
|
||||
3
|
||||
7
|
||||
12
|
||||
*/
|
||||
```
|
||||
|
||||
#### While loop
|
||||
|
||||
```js
|
||||
while(conditionLikeIf)
|
||||
{
|
||||
Console.WriteLine("Hi");
|
||||
}
|
||||
|
||||
//If conditionLikeIf is falsey we never print Hi
|
||||
//If conditionLikeIf is truthy we print Hi until it is falsey
|
||||
```
|
||||
|
||||
#### Do loop
|
||||
|
||||
```js
|
||||
do(conditionLikeIf)
|
||||
{
|
||||
Console.WriteLine("Hi");
|
||||
}
|
||||
|
||||
//If conditionLikeIf is falsey we print Hi once
|
||||
//If conditionLikeIf is truthy we print Hi until it is falsey
|
||||
```
|
||||
|
||||
|
||||
|
||||
#### Try statement
|
||||
|
||||
Note: you can't yield, return, break or continue from inside a try statement (also applys to catch and finally due to these being internally closures)
|
||||
|
||||
```js
|
||||
try {
|
||||
Console.WriteLine("God is good.");
|
||||
throw "my error";
|
||||
Console.WriteLine("I am lonely, I am never called.");
|
||||
}
|
||||
catch(ex)
|
||||
{
|
||||
Console.WriteLine($"I got an error {ex}.");
|
||||
}
|
||||
finally {
|
||||
Console.WriteLine("For God so loved the world that he gave his only begotten Son, that whoever believes in him should not perish but have eternal life.");
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
This should print
|
||||
God is good.
|
||||
I got an error my error.
|
||||
For God so loved the world that he gave his only begotten Son, that whoever believes in him should not perish but have eternal life.
|
||||
*/
|
||||
```
|
||||
|
||||
#### Switch statement
|
||||
|
||||
NOTE: you can use dictionaries with overloaded equals operator (we will pass the switch's expression as the argument)
|
||||
|
||||
```js
|
||||
o = {
|
||||
operator== = (this,v) => {
|
||||
//this is implicitly passed by runtime, but you must declare it if you want it
|
||||
return (v * 7) == 42;
|
||||
}
|
||||
};
|
||||
|
||||
var val = 6;
|
||||
|
||||
switch(val)
|
||||
{
|
||||
case 4:
|
||||
Console.WriteLine("I am four");
|
||||
break;
|
||||
case 5:
|
||||
Console.WriteLine("I am five");
|
||||
break;
|
||||
case o:
|
||||
Console.WriteLine("Hitchhiker's guide to the galaxy meaning of life");
|
||||
break;
|
||||
default:
|
||||
Console.WriteLine("We don't support it we are sorry");
|
||||
}
|
||||
```
|
||||
|
||||
|
||||
|
||||
#### Function declaration
|
||||
|
||||
```go
|
||||
//you can create functions on dictionaries so long as they are on root environment (they are declared there before root scope is evaluated so this is possible)
|
||||
My.Func.Joel = 59; //Because My.Func.Is.A.Few.Deep creates the dictionaries via runtime
|
||||
|
||||
func My.Func.Is.A.Few.Deep(a, b)
|
||||
{
|
||||
return a * b;
|
||||
}
|
||||
func main(args)
|
||||
{
|
||||
Console.WriteLine(My.Func.Is.A.Few.Deep(6,7));
|
||||
}
|
||||
```
|
||||
|
||||
#### Function inside a function
|
||||
|
||||
Oh yeah functions can have exclusively a expression as a body which does not need a return keyword
|
||||
|
||||
```go
|
||||
func main(args)
|
||||
{
|
||||
func MyOther(a,b) a * b;
|
||||
Console.WriteLine(MyOther(a,b));
|
||||
}
|
||||
```
|
||||
|
||||
#### Document a function
|
||||
|
||||
```go
|
||||
/^
|
||||
This function returns 42
|
||||
^/
|
||||
func MyFunction() 42;
|
||||
```
|
||||
|
||||
#### Return statement
|
||||
|
||||
You can also return nothing
|
||||
|
||||
```js
|
||||
return 42;
|
||||
return;
|
||||
```
|
||||
|
||||
#### Yield statement
|
||||
|
||||
This will halt the function's execution and return the running function object (were you can pop the item and resume it)
|
||||
|
||||
To automaticly make a function enumerable (with each statement) you must use ``enumerable`` instead of func when declaring your function
|
||||
|
||||
```js
|
||||
yield 42;
|
||||
```
|
||||
|
||||
#### Throw statement
|
||||
|
||||
You can catch this with ``try statement`` with ``catch`` clause
|
||||
|
||||
```js
|
||||
throw "You can replace me with another string or any other object";
|
||||
```
|
||||
|
||||
#### Defer statement
|
||||
|
||||
Your code will be called when your scope is destroyed
|
||||
|
||||
```go
|
||||
{
|
||||
defer {
|
||||
Console.WriteLine("In defer");
|
||||
}
|
||||
Console.WriteLine("About to leave scope");
|
||||
}
|
||||
Console.WriteLine("Left scope");
|
||||
|
||||
|
||||
/*
|
||||
The output should be
|
||||
|
||||
About to leave scope
|
||||
In defer
|
||||
Left scope
|
||||
*/
|
||||
```
|
||||
|
||||
## Expressions
|
||||
|
||||
We will place it as a parameter to a function ``doThing`` but these will work anywhere like setting a variable or another expression
|
||||
|
||||
#### Undefined
|
||||
|
||||
```js
|
||||
doThing(undefined);
|
||||
```
|
||||
|
||||
#### Null
|
||||
|
||||
```js
|
||||
doThing(null);
|
||||
```
|
||||
|
||||
#### Boolean
|
||||
|
||||
```js
|
||||
doThing(false);
|
||||
doThing(true);
|
||||
```
|
||||
|
||||
#### Long
|
||||
|
||||
A signed 64 bit number
|
||||
|
||||
```js
|
||||
doThing(94);
|
||||
doThing(599929022);
|
||||
```
|
||||
|
||||
#### Double
|
||||
|
||||
A 64 bit floating pointer number
|
||||
|
||||
```js
|
||||
doThing(5.25);
|
||||
doThing(942.90204);
|
||||
```
|
||||
|
||||
#### Char
|
||||
|
||||
Yes we support single character strings (this escapes a double quote)
|
||||
|
||||
```csharp
|
||||
doThing('\"');
|
||||
```
|
||||
|
||||
#### String
|
||||
|
||||
Second is an interopolated string
|
||||
|
||||
```csharp
|
||||
doThing("Hi");
|
||||
doThing($"My name is {name}");
|
||||
```
|
||||
|
||||
#### List
|
||||
|
||||
```js
|
||||
doThing(
|
||||
[4,5,9,42,true,"Hi",'\n']
|
||||
);
|
||||
```
|
||||
|
||||
#### Dictionary
|
||||
|
||||
```js
|
||||
doThing(
|
||||
{
|
||||
a = "This is an option",
|
||||
b = 42,
|
||||
c = 9
|
||||
}
|
||||
);
|
||||
```
|
||||
|
||||
###### Enumerating a dictionary
|
||||
|
||||
```js
|
||||
var dict = { a = 5, b = 42};
|
||||
each(var item : Dictionary.Items(dict))
|
||||
{
|
||||
Console.WriteLine($"Key: {item.Key}");
|
||||
Console.WriteLine($"Value: {item.Value}");
|
||||
Console.WriteLine();
|
||||
}
|
||||
/*
|
||||
This prints
|
||||
Key: a
|
||||
Value: 5
|
||||
|
||||
Key: b
|
||||
Value: 42
|
||||
|
||||
*/
|
||||
```
|
||||
|
||||
|
||||
|
||||
###### Getting a value from dictionary
|
||||
|
||||
```go
|
||||
func doThing(data)
|
||||
{
|
||||
Console.WriteLine(data.b); //will print 42
|
||||
}
|
||||
```
|
||||
|
||||
###### Setting a value to dictionary
|
||||
|
||||
```go
|
||||
func doThing(data)
|
||||
{
|
||||
data.a = true; //replace a with a different value
|
||||
data.someFieldThatDoesNotExist = 9; //define a new field entirely
|
||||
|
||||
}
|
||||
```
|
||||
|
||||
###### Methods
|
||||
|
||||
Note that this is optional but if you do have it it must be the first argument, the this argument points to the dictionary
|
||||
|
||||
```go
|
||||
var item = {
|
||||
myMethod = (this, a, b) => {
|
||||
return a * b;
|
||||
}
|
||||
};
|
||||
|
||||
Console.WriteLine(item.myMethod(6,7)); //prints 42
|
||||
```
|
||||
|
||||
Or
|
||||
|
||||
```go
|
||||
var item = {};
|
||||
func item.myMethod(this, a, b)
|
||||
{
|
||||
return a * b;
|
||||
}
|
||||
Console.WriteLine(item.myMethod(6,7)); //prints 42
|
||||
```
|
||||
|
||||
###### Properties
|
||||
|
||||
They are declared like every other method except they are prefixed with ``get`` or ``set``
|
||||
|
||||
```go
|
||||
var item = {
|
||||
getProp = (this)=>{
|
||||
return 42;
|
||||
},
|
||||
setProp = (this,v)=>{
|
||||
//do something with v
|
||||
}
|
||||
};
|
||||
|
||||
Console.WriteLine(item.Prop); //equivalent to Console.WriteLine(item.getProp());
|
||||
|
||||
item.Prop = 100; //equivalent to item.setProp(100); will do nothing in this example
|
||||
|
||||
```
|
||||
|
||||
###### Operator overloading
|
||||
|
||||
```js
|
||||
var item = {
|
||||
operator+ = (this,right) => {
|
||||
return 4 + a;
|
||||
}
|
||||
operator- = (this,right) => {
|
||||
return 4 - right; //be careful right may be undefined if the negate operator is used
|
||||
}
|
||||
};
|
||||
|
||||
Console.WriteLine(item + 5); //prints 9
|
||||
```
|
||||
|
||||
###### Array operator overloading
|
||||
|
||||
```js
|
||||
var item = {
|
||||
GetAt = (index)=>{
|
||||
return index * 2; //we multiply index by two and return
|
||||
},
|
||||
SetAt => (index,value)=>{
|
||||
Console.WriteLine($"The index was {index} and value was {value}");
|
||||
}
|
||||
};
|
||||
|
||||
Console.WriteLine(item[21]); //prints 42
|
||||
item["Hi"] = "John"; //prints The index was Hi and value was John
|
||||
```
|
||||
|
||||
#### ByteArray
|
||||
|
||||
```js
|
||||
var bA = new ByteArray(1);
|
||||
ba[0] = 42;
|
||||
Console.WriteLine(ba.ToString()); //prints *
|
||||
```
|
||||
|
||||
###### ByteArray from string
|
||||
|
||||
```js
|
||||
var bA = new ByteArray("Hi");
|
||||
//we can get bytes like this bA[0] which will be 72
|
||||
//we can get length by bA.Count or bA.Length
|
||||
```
|
||||
|
||||
#### Embedding files (you can't do this easily in C/C++ and C# not as easy as this)
|
||||
|
||||
```js
|
||||
var bA = embed("myFile.png"); //will embed the file res/myFile.png
|
||||
//it is stored as a RESO in the crvm file and bA is a ByteArray
|
||||
//note the argument MUST be a constant string
|
||||
//note you can access a subdirectory of res as well just use dir/file.bin
|
||||
```
|
||||
|
||||
#### Streams
|
||||
|
||||
|
||||
|
||||
###### From an existing file
|
||||
|
||||
```js
|
||||
var strm = FS.Local.OpenFile("file.bin","rb");
|
||||
|
||||
var data = new ByteArray(1024);
|
||||
var read = strm.Read(data,0,data.Count);
|
||||
//use ReadBlock to ensure you have 1024 bytes if not near end of stream
|
||||
|
||||
//use WriteBlock to ensure you write the amount you say you need
|
||||
|
||||
strm.Close();
|
||||
```
|
||||
|
||||
#### VFS
|
||||
|
||||
```js
|
||||
var myVFS = FS.Local; //FS.Local is the local filesystem
|
||||
|
||||
|
||||
myVFS.CreateDirectory("myDir"); //creates directory in current dir (only local)
|
||||
|
||||
myVFS.DeleteDirectory("myDir"); //now we delete it
|
||||
|
||||
|
||||
myVFS.CreateDirectory(Path.FromString(Env.Downloads) / "Folder in Downloads"); //Create a folder in downloads
|
||||
```
|
||||
|
||||
|
||||
|
||||
#### Path
|
||||
|
||||
```js
|
||||
var path = / "Path" / "To" / "Directory";
|
||||
var relativePath = ./"another"/"path";
|
||||
var combined = path / relativePath;
|
||||
var someString = "joel";
|
||||
var combinedAndStr = combined / someString;
|
||||
var combinedWithExtension = combined + ".mp4";
|
||||
Console.WriteLine(combined); // outputs /Path/To/Directory/another/path
|
||||
Console.WriteLine(combined); // outputs /Path/To/Directory/another/path/joel
|
||||
Console.WriteLine(combinedWithExtension); //outputs /Path/To/Directory/another/path.mp4
|
||||
//these paths are used with vfs
|
||||
|
||||
|
||||
//to get parent directory use combined.GetParent();
|
||||
//to get filename use combined.GetFileName();
|
||||
//to get extension use combinedWithExtension.GetExtension();, it will be the extension including .
|
||||
//to change the extension use combinedWithExtension.ChangeExtension(".mkv");
|
||||
//to remove the extension use combinedWithExtension.ChangeExtension(null); or combinedWithExtension.ChangeExtension();
|
||||
```
|
||||
|
||||
#### Html Litterals
|
||||
```go
|
||||
//comments are just crosslang ones
|
||||
|
||||
//we will be setting to myHtml for the html (returns a string) (it is already html escaped)
|
||||
myHtml = <h1>{someStringExpression}</h1>;
|
||||
|
||||
//a link, in this example we have a dictionary named node with string fields href and text
|
||||
//lets say node.text equaled List<int> and href contained ./mypage?name=Joel&file=steve.bin myHtml would be equal to "<a target=\"_blank\" href=\"./mypage?name=Joel&file=steve.bin\">List<int></a>" (the \ are just there to make this a valid string for demonstration purposes, there aren't really backslashes)
|
||||
myHtml = <a target="_blank" href={node.href}>{node.text}</a>;
|
||||
|
||||
|
||||
//for (works like for loop but is in html form, the for part is not rendered in the final string)
|
||||
myHtml = <for(var i = 0; i < 42; i++)>
|
||||
<h6>{i}</h6>
|
||||
</for>;
|
||||
|
||||
//each
|
||||
myHtml = <each(var item : list)></each>;
|
||||
|
||||
//do
|
||||
myHtml = <do(expr == 42)></do>;
|
||||
|
||||
//while
|
||||
myHtml = <while(expr == 42)></while>;
|
||||
|
||||
//if
|
||||
|
||||
myHtml = <if(expr == 42)>
|
||||
<true>
|
||||
//if expr is 42
|
||||
</true>
|
||||
<false>
|
||||
//if expr is not 42
|
||||
//you would use another if here instead of else if
|
||||
</false>
|
||||
</if>;
|
||||
|
||||
myHtml = <null>Hello</null>; //would just be Hello (useful for templating as it works just like div but the null part is not emited into string)
|
||||
|
||||
myHtml = <raw(stringExpr)>; //allowing you to emit unescaped html from string into html litteral (useful for templating)
|
||||
```
|
||||
|
||||
16
content/language-features/creating-a-project.md
Normal file
16
content/language-features/creating-a-project.md
Normal file
@@ -0,0 +1,16 @@
|
||||
+++
|
||||
title = 'Creating a project'
|
||||
date = 2025-05-08T22:23:44-05:00
|
||||
+++
|
||||
|
||||
### Console application
|
||||
|
||||
```bash
|
||||
mkdir proj_name
|
||||
cd proj_name
|
||||
crosslang new console
|
||||
|
||||
# edit the src/main.tcross
|
||||
|
||||
crosslang run
|
||||
```
|
||||
44
content/language-features/working-with-files.md
Normal file
44
content/language-features/working-with-files.md
Normal file
@@ -0,0 +1,44 @@
|
||||
+++
|
||||
title = 'Working with files'
|
||||
date = 2025-05-08T22:23:44-05:00
|
||||
+++
|
||||
|
||||
## Write text to file
|
||||
```go
|
||||
FS.WriteAllText(FS.Local, "file.txt", "Some text");
|
||||
```
|
||||
|
||||
## Read text from file
|
||||
```go
|
||||
var text = FS.ReadAllText(FS.Local, "file.txt");
|
||||
```
|
||||
|
||||
## Create a directory
|
||||
```go
|
||||
FS.Local.CreateDirectory("New Folder");
|
||||
FS.Local.CreateDirectory("Folder" / "Another Folder"); // we can create folders even if parents don't exist
|
||||
```
|
||||
|
||||
## Enumerating entries in folder
|
||||
```go
|
||||
each(var file : FS.Local.EnumeratePaths(/))
|
||||
{
|
||||
if(FS.Local.DirectoryExists(file)) Console.Write("DIR ");
|
||||
|
||||
Console.WriteLine(file);
|
||||
}
|
||||
```
|
||||
|
||||
### Exists
|
||||
```go
|
||||
FS.Local.FileExists("/path/to/file"); //use FS.Local.RegularFileExists("/path/to/file"); if you don't want special files to be considered
|
||||
FS.Local.DirectoryExists("/path/to/directory");
|
||||
```
|
||||
|
||||
### Opening files
|
||||
See [Streams](streams.md) for more details on the Stream object
|
||||
```go
|
||||
var strm = FS.Local.OpenFile("/path/to/file.bin", "rb");
|
||||
//use strm.Read(buffer,buffer_offset,length); to read some data, returns number of bytes read
|
||||
strm.Close();
|
||||
```
|
||||
4
hugo.toml
Normal file
4
hugo.toml
Normal file
@@ -0,0 +1,4 @@
|
||||
baseURL = 'https://crosslang.tesseslanguage.com/'
|
||||
languageCode = 'en-us'
|
||||
title = 'CrossLang'
|
||||
theme = 'hugo-theme-relearn'
|
||||
4
static/images/favicon.svg
Normal file
4
static/images/favicon.svg
Normal file
@@ -0,0 +1,4 @@
|
||||
<svg xmlns='http://www.w3.org/2000/svg' xmlns:xlink='http://www.w3.org/1999/xlink' aria-hidden='true' role='img' class='iconify iconify--logos' width="100" height="100">
|
||||
<polygon points="50,0,100,25,100,75,50,100,0,75,0,25" style="fill:orange;stroke:black;stroke-width:3" />
|
||||
<polygon points="45,20,55,20,55,35,80,35,80,45,55,45,55,85,45,85,45,45,20,45,20,35,45,35" style="fill:white;stroke:black;stroke-width:3"/>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 428 B |
1
themes/hugo-theme-relearn
Submodule
1
themes/hugo-theme-relearn
Submodule
Submodule themes/hugo-theme-relearn added at 0b83617ee9
Reference in New Issue
Block a user