# gscript
**Repository Path**: crossoverJie/gscript
## Basic Information
- **Project Name**: gscript
- **Description**: 💪🏻This is a statically and strongly typed language written in Go.
- **Primary Language**: Go
- **License**: BSD-3-Clause
- **Default Branch**: main
- **Homepage**: None
- **GVP Project**: No
## Statistics
- **Stars**: 3
- **Forks**: 1
- **Created**: 2022-09-14
- **Last Updated**: 2022-09-30
## Categories & Tags
**Categories**: Uncategorized
**Tags**: None
## README
```
_ _
___ ___ ___ ___|_|___| |_
| . |_ -| _| _| | . | _|
|_ |___|___|_| |_| _|_|
|___| |_|
```
📘[特性](#特性) | 🌰[例子](#例子) | 👾[REPL](#repl) | 🎉[语法](#语法) | 🎁[标准库](#标准库) | 🔧[安装](https://github.com/crossoverJie/gscript/releases) | 💡[联系作者](#联系作者) | 🇦🇺[英文文档](https://github.com/crossoverjie/gscript/blob/master/README.md)
# 介绍
这是一门用 Go 编写的一款**静态、强类型**的脚本语言,大部分语法参考了 `Java` 以及少量的 `Go`。
> 当前版本仅供学习与实验。
运行:
hello_world.gs:
```js
println("hello world");
```
```shell
❯ gscript hello_world.gs
hello world
```
# 特性
- [x] [class声明](#class)
- [x] [函数声明与调用](#函数)
- [x] [基本类型](#基本类型): `int/string/float/bool`
- [x] [array数组类型](#数组)
- [x] `any` [通用类型](#any)
- [x] 特殊类型 `nil`
- [x] 函数类型
- [x] [闭包:函数一等公民](#闭包)
- [x] [内置函数](#内置函数): `len()/hash()/assertEqual()/JSON()/JSONGet()`
- [x] [标准库](#标准库)
- [x] [Map](#map)
- [x] [可变参数](#可变参数)
- [x] [运算符重载](#运算符重载)
- [x] [原生 `json` 支持](#内置函数)
- [x] [原生 `http` 包支持](#http)
- [x] 案例
- [x] LeetCode
- [x] [判断链表是否有环 ](https://github.com/crossoverJie/gscript/blob/main/example/linked_list_cycle141.gs)
- [x] [两数之和](https://github.com/crossoverJie/gscript/blob/main/example/leetcode/two_sum.gs)
- [x] [打印斐波那契数列 ](#打印斐波那契数列)
- [x] [HTTP Service](https://github.com/crossoverJie/gscript/blob/main/example/http_server.gs)
- [ ] 单测命令行工具
# 例子
## Hello world
```js
println("hello world");
```
## 打印斐波那契数列
```js
func int() fib(){
int a = 0;
int b = 1;
int fibonacci(){
int c = a;
a = b;
b = a+c;
return c;
}
return fibonacci;
}
func int() f = fib();
for (int i = 0; i < 10; i++){
println(f());
}
```
## 网站应用
这是用 `GScript` 编写的动态网页:
[https://gscript.crossoverjie.top/index](https://gscript.crossoverjie.top/index)
源码地址:
[https://github.com/crossoverjie/gscript-homepage](https://github.com/crossoverjie/gscript-homepage)
---
更多例子:[https://github.com/crossoverJie/gscript/tree/main/example](https://github.com/crossoverJie/gscript/tree/main/example)
# REPL
```shell
> ./gscript
```

# 语法
## 基本类型
当前版本支持 `int/string/float/bool` 四种基本类型以及 `nil` 特殊类型。
变量声明语法:`type identifier (= expr)?`。
```js
int a=10;
string b,c;
float e = 10.1;
bool f = false;
string x = `
{
"name": "bob",
"age": 20,
"skill": {
"lang": [
{
"go": {
"feature": [
"goroutine",
true
]
}
}
]
}
}
`;
```
## 数组
数组声明语法:`('[' DECIMAL_LITERAL ']')? '{' (variableInitializer (',' variableInitializer)* (',')? )? '}'`
```js
// 声明并初始化
int[] a={1,2,3};
println(a);
// 声明一个空数组并指定大小
int[] table = [4]{};
println();
// 向数组 append 数据
a = append(a,4);
println(a);
for(int i=0;i 当函数没有返回值时,可以声明为 void 或直接忽略返回类型。
## 闭包
在 `GScript` 中,函数作为一等公民可以作为变量传递,同时也能实现闭包。
函数类型语法:`func typeTypeOrVoid '(' typeList? ')'`
```js
// 外部变量,全局共享。
int varExternal =10;
func int(int) f1(){
// 闭包变量对每个闭包单独可见
int varInner = 20;
int innerFun(int a){
println(a);
int c=100;
varExternal++;
varInner++;
return varInner;
}
return innerFun;
}
// f2 作为一个函数类型,接收的是一个返回值和参数都是 int 的函数。
func int(int) f2 = f1();
for(int i=0;i<2;i++){
println("varInner=" + f2(i) + ", varExternal=" + varExternal);
}
println("=======");
func int(int) f3 = f1();
for(int i=0;i<2;i++){
println("varInner=" + f3(i) + ", varExternal=" + varExternal);
}
```
最终输出如下:
```shell
0
varInner=21, varExternal=11
1
varInner=22, varExternal=12
=======
0
varInner=21, varExternal=13
1
varInner=22, varExternal=14
```
## 可变参数
`GScript` 支持函数定义可变参数,语法如下:
```js
int add(string s, int ...num){
println(s);
int sum = 0;
for(int i=0;i >=`
> 重载函数名称必须是 **operator**,名称后跟上运算符即可重载。
```js
class Person{
int age;
Person(int a){
age = a;
}
}
Person operator + (Person p1, Person p2){
Person pp = Person(p1.age+p2.age);
return pp;
}
Person operator - (Person p1, Person p2){
Person pp = Person(p1.age-p2.age);
return pp;
}
Person operator * (Person p1, Person p2){
Person pp = Person(p1.age * p2.age);
return pp;
}
Person operator / (Person p1, Person p2){
Person pp = Person(p1.age / p2.age);
return pp;
}
bool operator == (Person p1, Person p2){
return p1.age==p2.age;
}
bool operator != (Person p1, Person p2){
return p1.age!=p2.age;
}
bool operator > (Person p1, Person p2){
return p1.age>p2.age;
}
bool operator >= (Person p1, Person p2){
return p1.age>=p2.age;
}
bool operator < (Person p1, Person p2){
return p1.age p2;
println("b3=="+b3);
assertEqual(b3,false);
bool b4 = p1 >= p2;
println("b4=="+b4);
assertEqual(b4,false);
bool b5 = p1 < p2;
println("b5=="+b5);
assertEqual(b5,true);
bool b6 = p1 <= p2;
println("b6=="+b6);
assertEqual(b6,true);
```
更多样例请参考:[https://github.com/crossoverJie/gscript/tree/main/example](https://github.com/crossoverJie/gscript/tree/main/example)
# 标准库
标准库源码:[https://github.com/crossoverJie/gscript/tree/main/internal](https://github.com/crossoverJie/gscript/tree/main/internal)
## 内置函数
```js
printf("hello %s ","123");
printf("hello-%s-%s ","123","abc");
printf("hello-%s-%d ","123",123);
string s = sprintf("nice to meet %s", "you");
println(s);
assertEqual(s,"nice to meet you");
int[] a={1,2,3};
// len 返回数组大小
println(len(a));
// 向数组追加数据
append(a,4);
println(a);
// output: [1,2,3,4]
// 断言函数,不相等时会抛出运行时异常,并中断程序。
assertEqual(len(a),4);
// 返回 hashcode
int hashcode = hash(key);
// 序列化 JSON 字符串
class P{
string name;
P(string n){
name = n;
}
}
class Object{
P p;
int x;
Object(P pp, int xx){
p = pp;
x = xx;
}
}
P p1 = P("abc");
Object o1 = Object(p1, 100);
string json = JSON(o1);
println(json); //{"p":{"name":"abc"},"x":100}
// 查询 JSON
int x = JSONGet(json,"x");
println(x);
assertEqual(x,100);
string name = JSONGet(json,"p.name");
println(name);
assertEqual(name,"abc");
// 获取启动参数
string[] args = getOSArgs();
```
> 更多 JSON 查询语法请参考:[xjson](https://github.com/crossoverJie/xjson#arithmetic-syntax)
## Map
函数定义:
```js
class Map{
put(any key, any value){}
any get(any key){}
}
```
```js
int count =100;
Map m1 = Map();
for (int i=0;i
hello
current ^+ local +^
hahaha