diff --git a/doc/syntax.md b/doc/syntax.md new file mode 100644 index 0000000..0e8fbb6 --- /dev/null +++ b/doc/syntax.md @@ -0,0 +1,594 @@ +## Gscript Syntax + +### Type + +Following are most used types in gscript: + +```python +100 # Number +100.21 # Number +"gscript" # String +false # Boolean +[1,"gs",{}] # Array +{foo: 1, bar:"bar"} # Objet +func(){} # Closure +nil # nil +``` + +**Array** + +```python +let arr = [1,2,[1,2,3]] +arr[0] # 1 +arr[2][2] # 3 +arr[3] # will panic +``` + +**Object** + +```python +let obj = { + foo:"foo", + bar:{ + 1:"1", + arr:[1,2,nil], + }, +} + +obj["foo"] # "foo" +obj.foo # "foo" +obj.bar[1] # "1" +obj.bar.arr # [1,2,nil] +``` + +### Variables and Scopes + +Use keyword `let` to define a new local variable. Using undefined variable will make compile failed: + +```python +let a = 1 + +# enter a new scope +{ + print(a) # a==1 + let a = 2 + let b = 3 + print(a) # a==2 + print(b) # b==3 +} + +print(a) # a==1 +print(b) # invalid, complie will not pass +``` + +Every variable can only be used in a scope, using a variable outside the scope will make compile failed, too. + +Like many other script language, a variable can be assigned to a new value of different type. + +```python +let a = {} +a = [] # ok +``` + +We can define multiple variables using one `let`: + +```python +let a, b = 1, "hello" # a=1,b="hello" +let a, b = 1 # a=1,b=nil +let a = 1,"hello" # a=1 +``` + +Of course, we can assign to multiple variables use one `=`: + +```python +let a,b +a, b = 1, 2 +``` + +### Operators + +**Unary Operators** + +| Operator | Usage | Types | +| :------: | :--------------: | :--------------------: | +| `~` | bitwise negation | Integer | +| `-` | `0 - x` | Number(Integer, Float) | +| `!` | `!x` | all | +| `--` | `--x` or `x--` | Number | +| `++` | `++x` or `x++` | Number | + +Be careful to use `--` and `++`. + +If these two operators are used as a statement: + +```python +# x++ is the same as ++x +let x = 0 +x++ # x==1 +++x # x==2 + +# x-- is the same as --x +x-- # x==1 +--x # x==0 +``` + +But if these two operators are used as a expression: + +```python +let x = 0 +print(x++) # output: 0 +print(++x) # output: 2 +print(--x) # output: 1 +print(x--) # output: 1 +# now x==0 +``` + +The behaviors of `--` and `++` are the same as language `JavaScript` and `C`. + +**Binary Operators** + +| Operator | Usage | Types | +| :------: | :------------: | :------------: | +| `+` | add | String, Number | +| `-` | sub | Number | +| `*` | multiply | Number | +| `/` | divide | Number | +| `//` | integer divide | Number | +| `%` | mod | Integer | +| `&` | bitwise AND | Integer | +| `|` | bitwise OR | Integer | +| `^` | bitwise XOR | Integer | +| `>>` | shrift right | Integer | +| `<<` | shrift left | Integer | +| `<=` | LE | String, Number | +| `<` | LT | String, Number | +| `>=` | GE | String, Number | +| `>` | GT | String, Number | +| `==` | EQ | String, Number | +| `!=` | NE | String, Number | +| `&&` | logical AND | all | +| `||` | logical OR | all | +| `[]` | `object[key]` | Object | + +*note: output type of (number + string) will be a string.* + +**Ternary Operators** + +```python +# condition ? true expression : false expression +let result = 1 < 2 ? 1 : 2; +print(result) # 1 +``` + +**Assignment Operators** + +| Operator | Example | Usage | +| :------: | :----------------------: | :---------------------: | +| `=` | `lhs[,lhs] = rhs[,rhs]` | `lhs[,lhs] = rhs[,rhs]` | +| `+=` | `lhs[,lhs] += rhs[,rhs]` | `lhs = lhs + rhs` | +| `-=` | `lhs[,lhs] -= rhs[,rhs]` | `lhs = lhs - rhs` | +| `*=` | `lhs[,lhs] *= rhs[,rhs]` | `lhs = lhs * rhs` | +| `/=` | `lhs[,lhs] /= rhs[,rhs]` | `lhs = lhs / rhs` | +| `%=` | `lhs[,lhs] %= rhs[,rhs]` | `lhs = lhs % rhs` | +| `&=` | `lhs[,lhs] &= rhs[,rhs]` | `lhs = lhs & rhs` | +| `^=` | `lhs[,lhs] ^= rhs[,rhs]` | `lhs = lhs ^ rhs` | +| `|=` | `lhs[,lhs] |= rhs[,rhs]` | `lhs = lhs | rhs` | + +**Operator Precedences** + +| Precedence | Operator | +| :--------: | :---------------: | +| 13 | `++` `--` | +| 12 | `-` `~` `!` | +| 11 | `/` `*` `%` `//` | +| 10 | `+` `-` | +| 9 | `>>` `<<` | +| 8 | `>` `<` `>=` `<=` | +| 7 | `==` `!=` | +| 6 | `&` | +| 5 | `^` | +| 4 | `|` | +| 3 | `&&` | +| 2 | `||` | +| 1 | `?:` | + +### Statements + +**If Statement** + +```python +if (a==1){ + print(1) +} +elif (a==2){ + print(2) +} +else { + print(3) +} +``` + +Use `{}` to mark a block. If there is only one statement in block, we can omit `{}`。 Code above is the same as following: + +```python +if (a==1) + print(1) +elif (a==2) + print(2) +else + print(3) +``` + +**While Statement** + +```python +while(true){ + # do something +} +``` + +If there is only one statement in block, we can omit `{}`. + +**For Statement** + +```python +for(let low,high=0,100;low