结构调整2
This commit is contained in:
79
ExampleCodes/1-Variables.fig
Normal file
79
ExampleCodes/1-Variables.fig
Normal file
@@ -0,0 +1,79 @@
|
||||
var any_var; // type is Any
|
||||
var number = 10; // type is Int
|
||||
number = "123"; // valid
|
||||
|
||||
var number2 := 10; // specific type is Int
|
||||
var number3: Int = 10; // both is ok
|
||||
/*
|
||||
number2 = 3.14;
|
||||
invalid!
|
||||
*/
|
||||
|
||||
const Pi := 3.14; // recommended, auto detect type
|
||||
// equal -> const Pi: Double = 3.14;
|
||||
|
||||
/*
|
||||
In fig, we have 13 builtin-type
|
||||
|
||||
01 Any
|
||||
02 Null
|
||||
03 Int
|
||||
04 String
|
||||
05 Bool
|
||||
06 Double
|
||||
07 Function
|
||||
08 StructType
|
||||
09 StructInstance
|
||||
10 List
|
||||
11 Map
|
||||
12 Module
|
||||
13 InterfaceType
|
||||
|
||||
3, 4, 5, 6, 10, 11 are initable
|
||||
|
||||
value system:
|
||||
object is immutable
|
||||
(included basic types: Int, String...)
|
||||
|
||||
`variable` is a name, refers to an object
|
||||
assignment is to bind name to value
|
||||
|
||||
Example: var a := 10;
|
||||
|
||||
[name] 'a' ---> variable slot (name, declared type, access modifier, [value) ---> ObjectPtr ---> raw Object class
|
||||
bind bind (shared_ptr)
|
||||
|
||||
For example:
|
||||
var a := 10;
|
||||
var b := 10;
|
||||
|
||||
`a` and `b` reference to the same object in memory
|
||||
|
||||
a = 20;
|
||||
|
||||
now a refers to a new object (20, Int)
|
||||
|
||||
what about complex types?
|
||||
they actually have same behaviors with basic types
|
||||
|
||||
var a := [1, 2, 3, 4];
|
||||
var b := a;
|
||||
|
||||
> a
|
||||
[1, 2, 3, 4]
|
||||
> b
|
||||
[1, 2, 3, 4]
|
||||
|
||||
set a[0] to 5
|
||||
|
||||
> a
|
||||
[5, 2, 3, 4]
|
||||
> b
|
||||
[5, 2, 3, 4]
|
||||
|
||||
Why did such a result occur?
|
||||
|
||||
" `a` and `b` reference to the same object in memory "
|
||||
|
||||
If you wish to obtain a copy, use List {a} to deeply copy it
|
||||
*/
|
||||
16
ExampleCodes/2-Function.fig
Normal file
16
ExampleCodes/2-Function.fig
Normal file
@@ -0,0 +1,16 @@
|
||||
import std.io;
|
||||
|
||||
func greeting(name:String) -> String
|
||||
{
|
||||
return "Hello " + name + "!";
|
||||
}
|
||||
|
||||
io.println(greeting("Fig"));
|
||||
|
||||
func adder(x)
|
||||
{
|
||||
return func (n) => x + n; // closure
|
||||
}
|
||||
|
||||
const add2 = adder(2);
|
||||
io.println(add2(3));
|
||||
30
ExampleCodes/3-Structure.fig
Normal file
30
ExampleCodes/3-Structure.fig
Normal file
@@ -0,0 +1,30 @@
|
||||
import std.io;
|
||||
|
||||
struct Point
|
||||
{
|
||||
x: Int; // type specifiers are optional
|
||||
y: Int; // type specifiers are optional
|
||||
|
||||
// x and y are private fields, can only reached by internal context
|
||||
|
||||
public func toString() -> String
|
||||
{
|
||||
return "(" + (x as String) + "," + (y as String) + ")";
|
||||
}
|
||||
// public func toString() {} is ok
|
||||
}
|
||||
|
||||
// make points
|
||||
|
||||
var p1 := new Point{1, 2};
|
||||
io.println(p1.toString()); // (1,2)
|
||||
|
||||
var p2 := new Point{x: 2, y: 3};
|
||||
io.println(p2.toString()); // (2,3)
|
||||
|
||||
var x := 114;
|
||||
var y := 514;
|
||||
|
||||
var p3 := new Point{y, x}; // shorthand mode, can be unordered, auto match field and variable!
|
||||
// = Point{x: x, y: y}
|
||||
io.println(p3.toString()); // (114,514)
|
||||
94
ExampleCodes/4-Interface.fig
Normal file
94
ExampleCodes/4-Interface.fig
Normal file
@@ -0,0 +1,94 @@
|
||||
import std.io;
|
||||
|
||||
interface Document
|
||||
{
|
||||
getDepth() -> Int; // return type is necessary
|
||||
getName() -> String;
|
||||
|
||||
/* toString() -> String
|
||||
{
|
||||
// default implementation
|
||||
}
|
||||
*/
|
||||
}
|
||||
|
||||
struct File
|
||||
{
|
||||
public depth: Int;
|
||||
public name: String;
|
||||
}
|
||||
|
||||
impl Document for File
|
||||
{
|
||||
getDepth()
|
||||
{
|
||||
return depth;
|
||||
}
|
||||
getName()
|
||||
{
|
||||
return name;
|
||||
}
|
||||
}
|
||||
|
||||
struct Folder
|
||||
{
|
||||
public depth: Int;
|
||||
public name: String;
|
||||
public childs: List = [];
|
||||
}
|
||||
|
||||
impl Document for Folder
|
||||
{
|
||||
getDepth()
|
||||
{
|
||||
return depth;
|
||||
}
|
||||
|
||||
getName()
|
||||
{
|
||||
return name;
|
||||
}
|
||||
}
|
||||
|
||||
const root_folder := new Folder{
|
||||
0,
|
||||
"root",
|
||||
[
|
||||
new File{
|
||||
1,
|
||||
"joyo.txt"
|
||||
},
|
||||
new Folder{
|
||||
2,
|
||||
"joyoyo",
|
||||
[
|
||||
new File{
|
||||
3,
|
||||
"JOYO2.txt"
|
||||
},
|
||||
new Folder{
|
||||
3,
|
||||
"joyoyoyo"
|
||||
|
||||
},
|
||||
]
|
||||
}
|
||||
]
|
||||
};
|
||||
|
||||
func print_directory(root: Document)
|
||||
{
|
||||
io.print(" " * root.getDepth());
|
||||
io.println(root.getDepth(), root.getName());
|
||||
if root is Folder
|
||||
{
|
||||
for var i := 0; i < root.childs.length(); i += 1
|
||||
{
|
||||
var child := root.childs[i];
|
||||
print_directory(child);
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
print_directory(root_folder);
|
||||
15
ExampleCodes/FigFig/main.fig
Normal file
15
ExampleCodes/FigFig/main.fig
Normal file
@@ -0,0 +1,15 @@
|
||||
import std.io;
|
||||
|
||||
import token {Token, TokenType};
|
||||
import tokenizer {Tokenizer};
|
||||
|
||||
const src := "abc egaD";
|
||||
const tokenizer := new Tokenizer{src};
|
||||
|
||||
const result := tokenizer.TokenizeAll();
|
||||
|
||||
for var i := 0; i < result.length(); i += 1
|
||||
{
|
||||
const tok := result[i];
|
||||
io.printf("{}: {}\n", tok.literal, tok.type);
|
||||
}
|
||||
31
ExampleCodes/FigFig/token.fig
Normal file
31
ExampleCodes/FigFig/token.fig
Normal file
@@ -0,0 +1,31 @@
|
||||
/*
|
||||
Example code: FigFig
|
||||
|
||||
Token.fig
|
||||
Copyright (C) 2020-2026 PuqiAR
|
||||
|
||||
*/
|
||||
struct _TokenTypes
|
||||
{
|
||||
public EOF = -1;
|
||||
public Identifier = 0;
|
||||
|
||||
public StringLiteral = 1;
|
||||
public NumberLiteral = 2;
|
||||
public True = 3;
|
||||
public False = 4;
|
||||
public Null = 5;
|
||||
|
||||
public Plus = 6;
|
||||
public Minus = 7;
|
||||
public Asterisk = 8;
|
||||
public Slash = 9;
|
||||
}
|
||||
|
||||
public const TokenType := new _TokenTypes{};
|
||||
|
||||
public struct Token
|
||||
{
|
||||
public literal: String = "";
|
||||
public type: Int = TokenType.EOF;
|
||||
}
|
||||
102
ExampleCodes/FigFig/tokenizer.fig
Normal file
102
ExampleCodes/FigFig/tokenizer.fig
Normal file
@@ -0,0 +1,102 @@
|
||||
/*
|
||||
Example code: FigFig
|
||||
|
||||
Tokenizer.fig
|
||||
Copyright (C) 2020-2026 PuqiAR
|
||||
|
||||
*/
|
||||
|
||||
import token {Token, TokenType};
|
||||
|
||||
func list_contains(lst: List, value: Any) -> Bool
|
||||
{
|
||||
for var i := 0; i < lst.length(); i += 1
|
||||
{
|
||||
if lst[i] == value
|
||||
{
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
func isspace(c: String) -> Bool
|
||||
{
|
||||
return c == " " || c == "\n" || c == "\t";
|
||||
}
|
||||
|
||||
func isalpha(c: String) -> Bool
|
||||
{
|
||||
const alb := [
|
||||
"a", "b", "c", "d",
|
||||
"e", "f", "g", "h",
|
||||
"i", "j", "k", "l",
|
||||
"m", "n", "o", "p",
|
||||
"q", "r", "s", "t",
|
||||
"u", "v", "w", "x",
|
||||
"y", "z",
|
||||
"A", "B", "C", "D",
|
||||
"E", "F", "G", "H",
|
||||
"I", "J", "K", "L",
|
||||
"M", "N", "O", "P",
|
||||
"Q", "R", "S", "T",
|
||||
"U", "V", "W", "X",
|
||||
"Y", "Z"
|
||||
];
|
||||
return list_contains(alb, c);
|
||||
}
|
||||
|
||||
|
||||
public struct Tokenizer
|
||||
{
|
||||
src: String = "";
|
||||
idx: Int = 0;
|
||||
|
||||
func next() -> Null
|
||||
{
|
||||
idx += 1;
|
||||
}
|
||||
|
||||
func hasNext() -> Bool
|
||||
{
|
||||
return idx < src.length();
|
||||
}
|
||||
|
||||
func produce() -> String
|
||||
{
|
||||
const tmp := src[idx];
|
||||
idx += 1;
|
||||
return tmp;
|
||||
}
|
||||
|
||||
func current() -> String
|
||||
{
|
||||
return src[idx];
|
||||
}
|
||||
|
||||
public func TokenizeAll() -> List
|
||||
{
|
||||
var output := [];
|
||||
|
||||
const push := func (tok: Token) => output.push(tok);
|
||||
|
||||
while hasNext()
|
||||
{
|
||||
while hasNext() && isspace(current())
|
||||
{
|
||||
next();
|
||||
}
|
||||
if isalpha(current())
|
||||
{
|
||||
var identi := "";
|
||||
while hasNext() && isalpha(current())
|
||||
{
|
||||
identi += produce();
|
||||
}
|
||||
push(new Token{identi, TokenType.Identifier});
|
||||
}
|
||||
}
|
||||
|
||||
return output;
|
||||
}
|
||||
}
|
||||
13
ExampleCodes/SpeedTest/fib.fig
Normal file
13
ExampleCodes/SpeedTest/fib.fig
Normal file
@@ -0,0 +1,13 @@
|
||||
import std.io;
|
||||
|
||||
func fib(x:Int) -> Int
|
||||
{
|
||||
if (x <= 1)
|
||||
{
|
||||
return x;
|
||||
}
|
||||
return fib(x-1) + fib(x-2);
|
||||
}
|
||||
|
||||
var result := fib(25);
|
||||
io.println("result: ", result);
|
||||
11
ExampleCodes/SpeedTest/fib.py
Normal file
11
ExampleCodes/SpeedTest/fib.py
Normal file
@@ -0,0 +1,11 @@
|
||||
from time import time as tt
|
||||
|
||||
def fib(x:int) -> int:
|
||||
if x <= 1: return x;
|
||||
return fib(x-1) + fib(x-2)
|
||||
|
||||
if __name__ == '__main__':
|
||||
t0 = tt()
|
||||
result = fib(30)
|
||||
t1 = tt()
|
||||
print('cost: ',t1-t0, 'result:', result)
|
||||
84
ExampleCodes/SpeedTest/fibBenchmark.fig
Normal file
84
ExampleCodes/SpeedTest/fibBenchmark.fig
Normal file
@@ -0,0 +1,84 @@
|
||||
import std.io;
|
||||
import std.time;
|
||||
import std.value;
|
||||
|
||||
func benchmark(fn: Function, arg: Any) -> Null
|
||||
{
|
||||
io.println("Testing fn:", fn, "with arg:", arg);
|
||||
const start := time.now();
|
||||
|
||||
const result := fn(arg);
|
||||
|
||||
const end := time.now();
|
||||
const duration := new time.Time{
|
||||
end.since(start)
|
||||
};
|
||||
io.println("=" * 50);
|
||||
io.println("fn returns:", result, "\n");
|
||||
io.println("Cost:", duration.toSeconds(), "s");
|
||||
io.println(" ", duration.toMillis(), "ms");
|
||||
}
|
||||
|
||||
var memo := {};
|
||||
|
||||
func fib_memo(x)
|
||||
{
|
||||
if memo.contains(x)
|
||||
{
|
||||
return memo.get(x);
|
||||
}
|
||||
if x <= 1
|
||||
{
|
||||
memo[x] = x;
|
||||
return x;
|
||||
}
|
||||
var result := fib_memo(x - 1) + fib_memo(x - 2);
|
||||
memo[x] = result;
|
||||
return result;
|
||||
}
|
||||
|
||||
func fib_iter(n)
|
||||
{
|
||||
var a := 0;
|
||||
var b := 1;
|
||||
for var i := 0; i < n; i = i + 1
|
||||
{
|
||||
var temp := a + b;
|
||||
a = b;
|
||||
b = temp;
|
||||
}
|
||||
return a;
|
||||
}
|
||||
|
||||
func fib(x)
|
||||
{
|
||||
if x <= 1
|
||||
{
|
||||
return x;
|
||||
}
|
||||
return fib(x - 1) + fib(x - 2);
|
||||
}
|
||||
|
||||
func fib_tail(n, a=0, b=1) {
|
||||
if n == 0 { return a; }
|
||||
if n == 1 { return b; }
|
||||
return fib_tail(n-1, b, a+b);
|
||||
}
|
||||
|
||||
const n := 30;
|
||||
|
||||
io.println("! fib(" + value.string_from(n) + "):");
|
||||
benchmark(fib, n);
|
||||
io.print("\n\n");
|
||||
|
||||
io.println("! fib_memo(" + value.string_from(n) + "):");
|
||||
benchmark(fib_memo, n);
|
||||
io.print("\n\n");
|
||||
|
||||
io.println("! fib_iter(" + value.string_from(n) + "):");
|
||||
benchmark(fib_iter, n);
|
||||
io.print("\n\n");
|
||||
|
||||
io.println("! fib_tail(" + value.string_from(n) + "):");
|
||||
benchmark(fib_tail, n);
|
||||
io.print("\n\n");
|
||||
27
ExampleCodes/SpeedTest/fibLoopTest.fig
Normal file
27
ExampleCodes/SpeedTest/fibLoopTest.fig
Normal file
@@ -0,0 +1,27 @@
|
||||
import std.io;
|
||||
import std.value;
|
||||
|
||||
var callCnt:Int = 0;
|
||||
func fib(x:Int) -> Int
|
||||
{
|
||||
callCnt = callCnt + 1;
|
||||
if (x <= 1)
|
||||
{
|
||||
return x;
|
||||
}
|
||||
return fib(x-1) + fib(x-2);
|
||||
}
|
||||
|
||||
var fibx:Int;
|
||||
io.print("input an index of fib ");
|
||||
fibx = value.int_parse(io.read());
|
||||
|
||||
var cnt:Int = 0;
|
||||
io.println("test forever");
|
||||
while (true)
|
||||
{
|
||||
cnt = cnt + 1;
|
||||
io.println("test ", cnt,",result: ", fib(fibx));
|
||||
io.println("func `fib` called ", callCnt);
|
||||
callCnt = 0;
|
||||
}
|
||||
29
ExampleCodes/use_std_test.fig
Normal file
29
ExampleCodes/use_std_test.fig
Normal file
@@ -0,0 +1,29 @@
|
||||
import std.io;
|
||||
import std.test;
|
||||
|
||||
var ascii_string_test := new test.Test{
|
||||
"ascii_string_test",
|
||||
func () => io.println("Hello," + " world!"),
|
||||
2
|
||||
};
|
||||
|
||||
var unicode_string_test := new test.Test{
|
||||
"unicode_string_test",
|
||||
func () => io.println("你好," + " 世界!"),
|
||||
2
|
||||
};
|
||||
|
||||
var unicode_string_inserting_test := new test.Test{
|
||||
"unicode_string_inserting_test",
|
||||
func (){
|
||||
var str := "我是你的粑粑";
|
||||
str.insert(1, "不");
|
||||
return str;
|
||||
},
|
||||
"我不是你的粑粑"
|
||||
};
|
||||
|
||||
var tests := [ascii_string_test, unicode_string_test, unicode_string_inserting_test];
|
||||
|
||||
var tester := new test.Tester{tests};
|
||||
tester.TestAll();
|
||||
Reference in New Issue
Block a user