aboutsummaryrefslogtreecommitdiff
path: root/examples
diff options
context:
space:
mode:
Diffstat (limited to 'examples')
-rw-r--r--examples/base64/base64.tm16
-rw-r--r--examples/colorful/README.md2
-rw-r--r--examples/colorful/colorful.tm62
-rw-r--r--examples/commands/commands.tm14
-rw-r--r--examples/game/game.tm8
-rw-r--r--examples/game/player.tm4
-rw-r--r--examples/game/raylib.tm42
-rw-r--r--examples/game/world.tm20
-rw-r--r--examples/http-server/connection-queue.tm18
-rw-r--r--examples/http-server/http-server.tm52
-rwxr-xr-xexamples/http-server/sample-site/random.tm2
-rw-r--r--examples/http/http.tm6
-rw-r--r--examples/ini/ini.tm30
-rw-r--r--examples/learnxiny.tm16
-rw-r--r--examples/log/log.tm14
-rw-r--r--examples/patterns/README.md38
-rw-r--r--examples/pthreads/pthreads.tm32
-rw-r--r--examples/random/README.md26
-rw-r--r--examples/random/random.tm26
-rw-r--r--examples/shell/shell.tm20
-rw-r--r--examples/time/time.tm40
-rw-r--r--examples/tomo-install/tomo-install.tm36
-rw-r--r--examples/tomodeps/tomodeps.tm58
-rw-r--r--examples/vectors/vectors.tm30
-rw-r--r--examples/wrap/wrap.tm34
25 files changed, 323 insertions, 323 deletions
diff --git a/examples/base64/base64.tm b/examples/base64/base64.tm
index e2f5ea19..714e223b 100644
--- a/examples/base64/base64.tm
+++ b/examples/base64/base64.tm
@@ -1,6 +1,6 @@
# Base 64 encoding and decoding
-_enc := "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/":bytes()
+_enc := "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/".bytes()
_EQUAL_BYTE := Byte(0x3D)
@@ -25,7 +25,7 @@ _dec : [Byte] = [
lang Base64:
func parse(text:Text -> Base64?):
- return Base64.from_bytes(text:bytes())
+ return Base64.from_bytes(text.bytes())
func from_bytes(bytes:[Byte] -> Base64?):
output := &[Byte(0) for _ in bytes.length * 4 / 3 + 4]
@@ -61,10 +61,10 @@ lang Base64:
return Base64.from_text(Text.from_bytes(output[]) or return none)
func decode_text(b64:Base64 -> Text?):
- return Text.from_bytes(b64:decode_bytes() or return none)
+ return Text.from_bytes(b64.decode_bytes() or return none)
func decode_bytes(b64:Base64 -> [Byte]?):
- bytes := b64.text:bytes()
+ bytes := b64.text.bytes()
output := &[Byte(0) for _ in bytes.length/4 * 3]
src := Int64(1)
dest := Int64(1)
@@ -83,14 +83,14 @@ lang Base64:
dest += 3
while output[-1] == 0xFF:
- output[] = output:to(-2)
+ output[] = output.to(-2)
return output[]
func main(input=(/dev/stdin), decode=no):
if decode:
- b := Base64.from_text(input:read()!)
- say(b:decode_text()!)
+ b := Base64.from_text(input.read()!)
+ say(b.decode_text()!)
else:
- text := input:read()!
+ text := input.read()!
say(Base64.parse(text)!.text)
diff --git a/examples/colorful/README.md b/examples/colorful/README.md
index b504a730..c03ace24 100644
--- a/examples/colorful/README.md
+++ b/examples/colorful/README.md
@@ -60,5 +60,5 @@ use colorful
$Colorful"
@(blue:Welcome to the @(bold:party)!)
We have @(green,bold:colors)!
-":print()
+".print()
```
diff --git a/examples/colorful/colorful.tm b/examples/colorful/colorful.tm
index 57a2a3d6..6769841d 100644
--- a/examples/colorful/colorful.tm
+++ b/examples/colorful/colorful.tm
@@ -11,7 +11,7 @@ use patterns
lang Colorful:
convert(text:Text -> Colorful):
- text = text:translate({"@"="@(at)", "("="@(lparen)", ")"="@(rparen)"})
+ text = text.translate({"@"="@(at)", "("="@(lparen)", ")"="@(rparen)"})
return Colorful.from_text(text)
convert(i:Int -> Colorful): return Colorful.from_text("$i")
@@ -21,13 +21,13 @@ lang Colorful:
return CSI ++ "m" ++ _for_terminal(c, _TermState())
func print(c:Colorful, newline=yes):
- say(c:for_terminal(), newline=newline)
+ say(c.for_terminal(), newline=newline)
func main(texts:[Text], files:[Path]=[], by_line=no):
for i,text in texts:
colorful := Colorful.from_text(text)
- colorful:print(newline=no)
+ colorful.print(newline=no)
if i == texts.length: say("")
else: say(" ", newline=no)
@@ -36,27 +36,27 @@ func main(texts:[Text], files:[Path]=[], by_line=no):
for file in files:
if by_line:
- for line in file:by_line() or exit("Could not read file: $file"):
+ for line in file.by_line() or exit("Could not read file: $file"):
colorful := Colorful.from_text(line)
- colorful:print()
+ colorful.print()
else:
- colorful := Colorful.from_text(file:read() or exit("Could not read file: $file"))
- colorful:print(newline=no)
+ colorful := Colorful.from_text(file.read() or exit("Could not read file: $file"))
+ colorful.print(newline=no)
func _for_terminal(c:Colorful, state:_TermState -> Text):
- return c.text:map_pattern(recursive=no, $Pat/@(?)/, func(m:PatternMatch): _add_ansi_sequences(m.captures[1], state))
+ return c.text.map_pattern(recursive=no, $Pat/@(?)/, func(m:PatternMatch): _add_ansi_sequences(m.captures[1], state))
enum _Color(Default, Bright(color:Int16), Color8Bit(color:Int16), Color24Bit(color:Int32)):
func from_text(text:Text -> _Color?):
- if text:matches_pattern($Pat/#{3-6 hex}/):
- hex := text:from(2)
+ if text.matches_pattern($Pat/#{3-6 hex}/):
+ hex := text.from(2)
return none unless hex.length == 3 or hex.length == 6
if hex.length == 3:
hex = hex[1]++hex[1]++hex[2]++hex[2]++hex[3]++hex[3]
n := Int32.parse("0x" ++ hex) or return none
return Color24Bit(n)
- else if text:matches_pattern($Pat/{1-3 digit}/):
+ else if text.matches_pattern($Pat/{1-3 digit}/):
n := Int16.parse(text) or return none
if n >= 0 and n <= 255: return Color8Bit(n)
else if text == "black": return _Color.Color8Bit(0)
@@ -118,20 +118,20 @@ enum _Color(Default, Bright(color:Int16), Color8Bit(color:Int16), Color24Bit(col
func _toggle(sequences:&[Text], cur,new:Bool, apply,unapply:Text; inline):
if new and not cur:
- sequences:insert(apply)
+ sequences.insert(apply)
else if cur and not new:
- sequences:insert(unapply)
+ sequences.insert(unapply)
func _toggle2(sequences:&[Text], cur1,cur2,new1,new2:Bool, apply1,apply2,unapply:Text; inline):
return if new1 == cur1 and new2 == cur2
if (cur1 and not new1) or (cur2 and not new2): # Gotta wipe at least one
- sequences:insert(unapply)
+ sequences.insert(unapply)
cur1, cur2 = no, no # Wiped out
if new1 and not cur1:
- sequences:insert(apply1)
+ sequences.insert(apply1)
if new2 and not cur2:
- sequences:insert(apply2)
+ sequences.insert(apply2)
struct _TermState(
bold=no, dim=no, italic=no, underline=no, blink=no,
@@ -154,35 +154,35 @@ struct _TermState(
_toggle2(sequences, old.subscript, old.subscript, new.superscript, new.superscript, "73", "74", "75")
if new.bg != old.bg:
- sequences:insert(new.bg:bg())
+ sequences.insert(new.bg.bg())
if new.fg != old.fg:
- sequences:insert(new.fg:fg())
+ sequences.insert(new.fg.fg())
if new.underline_color != old.underline_color:
- sequences:insert(new.underline_color:underline())
+ sequences.insert(new.underline_color.underline())
if sequences.length == 0:
return ""
- return CSI ++ ";":join(sequences) ++ "m"
+ return CSI ++ ";".join(sequences) ++ "m"
func _add_ansi_sequences(text:Text, prev_state:_TermState -> Text):
if text == "lparen": return "("
else if text == "rparen": return ")"
else if text == "@" or text == "at": return "@"
parts := (
- text:pattern_captures($Pat/{0+..}:{0+..}/) or
+ text.pattern_captures($Pat/{0+..}:{0+..}/) or
return "@("++_for_terminal(Colorful.from_text(text), prev_state)++")"
)
- attributes := parts[1]:split_pattern($Pat/{0+space},{0+space}/)
+ attributes := parts[1].split_pattern($Pat/{0+space},{0+space}/)
new_state := prev_state
for attr in attributes:
- if attr:starts_with("fg="):
- new_state.fg = _Color.from_text(attr:from(4))!
- else if attr:starts_with("bg="):
- new_state.bg = _Color.from_text(attr:from(4))!
- else if attr:starts_with("ul="):
- new_state.underline_color = _Color.from_text(attr:from(4))!
+ if attr.starts_with("fg="):
+ new_state.fg = _Color.from_text(attr.from(4))!
+ else if attr.starts_with("bg="):
+ new_state.bg = _Color.from_text(attr.from(4))!
+ else if attr.starts_with("ul="):
+ new_state.underline_color = _Color.from_text(attr.from(4))!
else if color := _Color.from_text(attr):
new_state.fg = color
else if attr == "b" or attr == "bold":
@@ -212,7 +212,7 @@ func _add_ansi_sequences(text:Text, prev_state:_TermState -> Text):
else:
fail("Invalid attribute: '$attr'")
- result := prev_state:apply(new_state)
- result ++= parts[2]:map_pattern(recursive=no, $Pat/@(?)/, func(m:PatternMatch): _add_ansi_sequences(m.captures[1], new_state))
- result ++= new_state:apply(prev_state)
+ result := prev_state.apply(new_state)
+ result ++= parts[2].map_pattern(recursive=no, $Pat/@(?)/, func(m:PatternMatch): _add_ansi_sequences(m.captures[1], new_state))
+ result ++= new_state.apply(prev_state)
return result
diff --git a/examples/commands/commands.tm b/examples/commands/commands.tm
index 170e45bc..6817fca1 100644
--- a/examples/commands/commands.tm
+++ b/examples/commands/commands.tm
@@ -3,8 +3,8 @@
use ./commands.c
use -lunistring
-extern run_command:func(exe:Text, args:[Text], env:{Text=Text}, input:[Byte]?, output:&[Byte]?, error:&[Byte]? -> Int32)
-extern command_by_line:func(exe:Text, args:[Text], env:{Text=Text} -> func(->Text?)?)
+extern run_command : func(exe:Text, args:[Text], env:{Text=Text}, input:[Byte]?, output:&[Byte]?, error:&[Byte]? -> Int32)
+extern command_by_line : func(exe:Text, args:[Text], env:{Text=Text} -> func(->Text?)?)
enum ExitType(Exited(status:Int32), Signaled(signal:Int32), Failed):
func succeeded(e:ExitType -> Bool):
@@ -12,7 +12,7 @@ enum ExitType(Exited(status:Int32), Signaled(signal:Int32), Failed):
else: return no
func or_fail(e:ExitType, message:Text?=none):
- if not e:succeeded():
+ if not e.succeeded():
fail(message or "Program failed: $e")
struct ProgramResult(stdout:[Byte], stderr:[Byte], exit_type:ExitType):
@@ -28,7 +28,7 @@ struct ProgramResult(stdout:[Byte], stderr:[Byte], exit_type:ExitType):
if status == 0:
if text := Text.from_bytes(r.stdout):
if trim_newline:
- text = text:without_suffix(\n)
+ text = text.without_suffix(\n)
return text
else: return none
return none
@@ -52,7 +52,7 @@ struct Command(command:Text, args:[Text]=[], env:{Text=Text}={}):
func result(command:Command, input="", input_bytes:[Byte]=[] -> ProgramResult):
if input.length > 0:
- (&input_bytes):insert_all(input:bytes())
+ (&input_bytes).insert_all(input.bytes())
stdout : [Byte] = []
stderr : [Byte] = []
@@ -78,10 +78,10 @@ struct Command(command:Text, args:[Text]=[], env:{Text=Text}={}):
return ExitType.Failed
func get_output(command:Command, input="", trim_newline=yes -> Text?):
- return command:result(input=input):output_text(trim_newline=trim_newline)
+ return command.result(input=input).output_text(trim_newline=trim_newline)
func get_output_bytes(command:Command, input="", input_bytes:[Byte]=[] -> [Byte]?):
- result := command:result(input=input, input_bytes=input_bytes)
+ result := command.result(input=input, input_bytes=input_bytes)
when result.exit_type is Exited(status):
if status == 0: return result.stdout
return none
diff --git a/examples/game/game.tm b/examples/game/game.tm
index 36ef14ff..ce08c329 100644
--- a/examples/game/game.tm
+++ b/examples/game/game.tm
@@ -5,24 +5,24 @@ use ./world.tm
func main(map=(./map.txt)):
InitWindow(1600, 900, CString("raylib [core] example - 2d camera"))
- map_contents := map:read() or exit("Could not find the game map: $map")
+ map_contents := map.read() or exit("Could not find the game map: $map")
world := @World(
player=@Player(Vector2(0,0), Vector2(0,0)),
goal=@Box(Vector2(0,0), Vector2(50,50), color=Color(0x10,0xa0,0x10)),
boxes=@[],
)
- world:load_map(map_contents)
+ world.load_map(map_contents)
SetTargetFPS(60)
while not WindowShouldClose():
dt := GetFrameTime()
- world:update(dt)
+ world.update(dt)
BeginDrawing()
ClearBackground(Color(0xCC, 0xCC, 0xCC, 0xFF))
- world:draw()
+ world.draw()
EndDrawing()
CloseWindow()
diff --git a/examples/game/player.tm b/examples/game/player.tm
index f73dcf6a..7f14f51e 100644
--- a/examples/game/player.tm
+++ b/examples/game/player.tm
@@ -16,11 +16,11 @@ struct Player(pos,prev_pos:Vector2):
target_y := inline C:Num32 {
(Num32_t)((IsKeyDown(KEY_W) ? -1 : 0) + (IsKeyDown(KEY_S) ? 1 : 0))
}
- target_vel := Vector2(target_x, target_y):norm() * Player.WALK_SPEED
+ target_vel := Vector2(target_x, target_y).norm() * Player.WALK_SPEED
vel := (p.pos - p.prev_pos)/World.DT
vel *= Player.FRICTION
- vel = vel:mix(target_vel, Player.ACCEL)
+ vel = vel.mix(target_vel, Player.ACCEL)
p.prev_pos, p.pos = p.pos, p.pos + World.DT*vel
diff --git a/examples/game/raylib.tm b/examples/game/raylib.tm
index ad248e4f..5e58e996 100644
--- a/examples/game/raylib.tm
+++ b/examples/game/raylib.tm
@@ -27,37 +27,37 @@ struct Vector2(x,y:Num32; extern):
func divided_by(v:Vector2, divisor:Num32->Vector2; inline):
return Vector2(v.x/divisor, v.y/divisor)
func length(v:Vector2->Num32; inline):
- return (v.x*v.x + v.y*v.y):sqrt()
+ return (v.x*v.x + v.y*v.y).sqrt()
func dist(a,b:Vector2->Num32; inline):
- return a:minus(b):length()
+ return a.minus(b).length()
func angle(v:Vector2->Num32; inline):
return Num32.atan2(v.y, v.x)
func norm(v:Vector2->Vector2; inline):
if v.x == 0 and v.y == 0:
return v
- len := v:length()
+ len := v.length()
return Vector2(v.x/len, v.y/len)
func rotated(v:Vector2, radians:Num32 -> Vector2):
- cos := radians:cos() or return v
- sin := radians:sin() or return v
+ cos := radians.cos() or return v
+ sin := radians.sin() or return v
return Vector2(cos*v.x - sin*v.y, sin*v.x + cos*v.y)
func mix(a,b:Vector2, amount:Num32 -> Vector2):
return Vector2(
- amount:mix(a.x, b.x),
- amount:mix(a.y, b.y),
+ amount.mix(a.x, b.x),
+ amount.mix(a.y, b.y),
)
-extern InitWindow:func(width:Int32, height:Int32, title:CString)
-extern SetTargetFPS:func(fps:Int32)
-extern WindowShouldClose:func(->Bool)
-extern GetFrameTime:func(->Num32)
-extern BeginDrawing:func()
-extern EndDrawing:func()
-extern CloseWindow:func()
-extern ClearBackground:func(color:Color)
-extern DrawRectangle:func(x,y,width,height:Int32, color:Color)
-extern DrawRectangleRec:func(rec:Rectangle, color:Color)
-extern DrawRectangleV:func(pos:Vector2, size:Vector2, color:Color)
-extern DrawText:func(text:CString, x,y:Int32, text_height:Int32, color:Color)
-extern GetScreenWidth:func(->Int32)
-extern GetScreenHeight:func(->Int32)
+extern InitWindow : func(width:Int32, height:Int32, title:CString)
+extern SetTargetFPS : func(fps:Int32)
+extern WindowShouldClose : func(->Bool)
+extern GetFrameTime : func(->Num32)
+extern BeginDrawing : func()
+extern EndDrawing : func()
+extern CloseWindow : func()
+extern ClearBackground : func(color:Color)
+extern DrawRectangle : func(x,y,width,height:Int32, color:Color)
+extern DrawRectangleRec : func(rec:Rectangle, color:Color)
+extern DrawRectangleV : func(pos:Vector2, size:Vector2, color:Color)
+extern DrawText : func(text:CString, x,y:Int32, text_height:Int32, color:Color)
+extern GetScreenWidth : func(->Int32)
+extern GetScreenHeight : func(->Int32)
diff --git a/examples/game/world.tm b/examples/game/world.tm
index 76acac6b..e8255ab8 100644
--- a/examples/game/world.tm
+++ b/examples/game/world.tm
@@ -44,11 +44,11 @@ struct World(player:@Player, goal:@Box, boxes:@[@Box], dt_accum=Num32(0.0), won=
func update(w:@World, dt:Num32):
w.dt_accum += dt
while w.dt_accum > 0:
- w:update_once()
+ w.update_once()
w.dt_accum -= World.DT
func update_once(w:@World):
- w.player:update()
+ w.player.update()
if solve_overlap(w.player.pos, Player.SIZE, w.goal.pos, w.goal.size) != Vector2(0,0):
w.won = yes
@@ -60,24 +60,24 @@ struct World(player:@Player, goal:@Box, boxes:@[@Box], dt_accum=Num32(0.0), won=
func draw(w:@World):
for b in w.boxes:
- b:draw()
- w.goal:draw()
- w.player:draw()
+ b.draw()
+ w.goal.draw()
+ w.player.draw()
if w.won:
DrawText(CString("WINNER"), GetScreenWidth()/Int32(2)-Int32(48*3), GetScreenHeight()/Int32(2)-Int32(24), 48, Color(0,0,0))
func load_map(w:@World, map:Text):
- if map:has("[]"):
- map = map:translate({"[]"="#", "@ "="@", " "=" "})
+ if map.has("[]"):
+ map = map.translate({"[]"="#", "@ "="@", " "=" "})
w.boxes = @[]
box_size := Vector2(50., 50.)
- for y,line in map:lines():
- for x,cell in line:split():
+ for y,line in map.lines():
+ for x,cell in line.split():
if cell == "#":
pos := Vector2((Num32(x)-1) * box_size.x, (Num32(y)-1) * box_size.y)
box := @Box(pos, size=box_size, color=Color(0x80,0x80,0x80))
- w.boxes:insert(box)
+ w.boxes.insert(box)
else if cell == "@":
pos := Vector2((Num32(x)-1) * box_size.x, (Num32(y)-1) * box_size.y)
pos += box_size/Num32(2) - Player.SIZE/Num32(2)
diff --git a/examples/http-server/connection-queue.tm b/examples/http-server/connection-queue.tm
index 84f92362..3c8058d5 100644
--- a/examples/http-server/connection-queue.tm
+++ b/examples/http-server/connection-queue.tm
@@ -5,21 +5,21 @@ func _assert_success(name:Text, val:Int32; inline):
struct ConnectionQueue(_connections:@[Int32]=@[], _mutex=pthread_mutex_t.new(), _cond=pthread_cond_t.new()):
func enqueue(queue:ConnectionQueue, connection:Int32):
- queue._mutex:lock()
- queue._connections:insert(connection)
- queue._mutex:unlock()
- queue._cond:signal()
+ queue._mutex.lock()
+ queue._connections.insert(connection)
+ queue._mutex.unlock()
+ queue._cond.signal()
func dequeue(queue:ConnectionQueue -> Int32):
conn : Int32? = none
- queue._mutex:lock()
+ queue._mutex.lock()
while queue._connections.length == 0:
- queue._cond:wait(queue._mutex)
+ queue._cond.wait(queue._mutex)
- conn = queue._connections:pop(1)
- queue._mutex:unlock()
- queue._cond:signal()
+ conn = queue._connections.pop(1)
+ queue._mutex.unlock()
+ queue._cond.signal()
return conn!
diff --git a/examples/http-server/http-server.tm b/examples/http-server/http-server.tm
index 1a09b601..649a9e12 100644
--- a/examples/http-server/http-server.tm
+++ b/examples/http-server/http-server.tm
@@ -19,9 +19,9 @@ func serve(port:Int32, handler:func(request:HTTPRequest -> HTTPResponse), num_th
connections := ConnectionQueue()
workers : &[@pthread_t] = &[]
for i in num_threads:
- workers:insert(pthread_t.new(func():
+ workers.insert(pthread_t.new(func():
repeat:
- connection := connections:dequeue()
+ connection := connections.dequeue()
request_text := inline C : Text {
Text_t request = EMPTY_TEXT;
char buf[1024] = {};
@@ -35,7 +35,7 @@ func serve(port:Int32, handler:func(request:HTTPRequest -> HTTPResponse), num_th
}
request := HTTPRequest.from_text(request_text) or skip
- response := handler(request):bytes()
+ response := handler(request).bytes()
inline C {
if (_$response.stride != 1)
Array$compact(&_$response, 1);
@@ -65,26 +65,26 @@ func serve(port:Int32, handler:func(request:HTTPRequest -> HTTPResponse), num_th
repeat:
conn := inline C : Int32 { accept(_$sock, NULL, NULL) }
stop if conn < 0
- connections:enqueue(conn)
+ connections.enqueue(conn)
say("Shutting down...")
for w in workers:
- w:cancel()
+ w.cancel()
struct HTTPRequest(method:Text, path:Text, version:Text, headers:[Text], body:Text):
func from_text(text:Text -> HTTPRequest?):
- m := text:pattern_captures($Pat'{word} {..} HTTP/{..}{crlf}{..}') or return none
+ m := text.pattern_captures($Pat'{word} {..} HTTP/{..}{crlf}{..}') or return none
method := m[1]
- path := m[2]:replace_pattern($Pat'{2+ /}', '/')
+ path := m[2].replace_pattern($Pat'{2+ /}', '/')
version := m[3]
- rest := m[-1]:pattern_captures($Pat/{..}{2 crlf}{0+ ..}/) or return none
- headers := rest[1]:split_pattern($Pat/{crlf}/)
+ rest := m[-1].pattern_captures($Pat/{..}{2 crlf}{0+ ..}/) or return none
+ headers := rest[1].split_pattern($Pat/{crlf}/)
body := rest[-1]
return HTTPRequest(method, path, version, headers, body)
struct HTTPResponse(body:Text, status=200, content_type="text/plain", headers:{Text=Text}={}):
func bytes(r:HTTPResponse -> [Byte]):
- body_bytes := r.body:bytes()
+ body_bytes := r.body.bytes()
extra_headers := (++: "$k: $v$(\r\n)" for k,v in r.headers) or ""
return "
HTTP/1.1 $(r.status) OK$\r
@@ -93,10 +93,10 @@ struct HTTPResponse(body:Text, status=200, content_type="text/plain", headers:{T
Connection: close$\r
$extra_headers
$\r$\n
- ":bytes() ++ body_bytes
+ ".bytes() ++ body_bytes
func _content_type(file:Path -> Text):
- when file:extension() is "html": return "text/html"
+ when file.extension() is "html": return "text/html"
is "tm": return "text/html"
is "js": return "text/javascript"
is "css": return "text/css"
@@ -105,30 +105,30 @@ func _content_type(file:Path -> Text):
enum RouteEntry(ServeFile(file:Path), Redirect(destination:Text)):
func respond(entry:RouteEntry, request:HTTPRequest -> HTTPResponse):
when entry is ServeFile(file):
- body := if file:can_execute():
- Command(Text(file)):get_output()!
+ body := if file.can_execute():
+ Command(Text(file)).get_output()!
else:
- file:read()!
+ file.read()!
return HTTPResponse(body, content_type=_content_type(file))
is Redirect(destination):
return HTTPResponse("Found", 302, headers={"Location"=destination})
func load_routes(directory:Path -> {Text=RouteEntry}):
routes : &{Text=RouteEntry} = &{}
- for file in (directory ++ (./*)):glob():
- skip unless file:is_file()
- contents := file:read() or skip
- server_path := "/" ++ "/":join(file:relative_to(directory).components)
- if file:base_name() == "index.html":
- canonical := server_path:without_suffix("index.html")
+ for file in (directory ++ (./*)).glob():
+ skip unless file.is_file()
+ contents := file.read() or skip
+ server_path := "/" ++ "/".join(file.relative_to(directory).components)
+ if file.base_name() == "index.html":
+ canonical := server_path.without_suffix("index.html")
routes[server_path] = Redirect(canonical)
routes[canonical] = ServeFile(file)
- else if file:extension() == "html":
- canonical := server_path:without_suffix(".html")
+ else if file.extension() == "html":
+ canonical := server_path.without_suffix(".html")
routes[server_path] = Redirect(canonical)
routes[canonical] = ServeFile(file)
- else if file:extension() == "tm":
- canonical := server_path:without_suffix(".tm")
+ else if file.extension() == "tm":
+ canonical := server_path.without_suffix(".tm")
routes[server_path] = Redirect(canonical)
routes[canonical] = ServeFile(file)
else:
@@ -142,7 +142,7 @@ func main(directory:Path, port=Int32(8080)):
serve(port, func(request:HTTPRequest):
if handler := routes[request.path]:
- return handler:respond(request)
+ return handler.respond(request)
else:
return HTTPResponse("Not found!", 404)
)
diff --git a/examples/http-server/sample-site/random.tm b/examples/http-server/sample-site/random.tm
index 502618e8..29b93be7 100755
--- a/examples/http-server/sample-site/random.tm
+++ b/examples/http-server/sample-site/random.tm
@@ -11,7 +11,7 @@ func main():
</head>
<body>
<h1>Random Number</h1>
- Your random number is: $(random:int(1,100))
+ Your random number is: $(random.int(1,100))
</body>
</html>
")
diff --git a/examples/http/http.tm b/examples/http/http.tm
index 12d9978e..048ffaab 100644
--- a/examples/http/http.tm
+++ b/examples/http/http.tm
@@ -10,7 +10,7 @@ enum _Method(GET, POST, PUT, PATCH, DELETE)
func _send(method:_Method, url:Text, data:Text?, headers:[Text]=[] -> HTTPResponse):
chunks : @[Text] = @[]
save_chunk := func(chunk:CString, size:Int64, n:Int64):
- chunks:insert(inline C:Text {
+ chunks.insert(inline C:Text {
Text$format("%.*s", _$size*_$n, _$chunk)
})
return n*size
@@ -79,7 +79,7 @@ func _send(method:_Method, url:Text, data:Text?, headers:[Text]=[] -> HTTPRespon
curl_easy_getinfo(curl, CURLINFO_RESPONSE_CODE, &_$code);
}
- return HTTPResponse(Int(code), "":join(chunks))
+ return HTTPResponse(Int(code), "".join(chunks))
func get(url:Text, headers:[Text]=[] -> HTTPResponse):
return _send(GET, url, none, headers)
@@ -99,7 +99,7 @@ func delete(url:Text, data:Text?=none, headers=["Content-Type: application/json"
func main():
say("GET:")
say(get("https://httpbin.org/get").body)
- say("Waiting 1sec...
+ say("Waiting 1sec...")
sleep(1)
say("POST:")
say(post("https://httpbin.org/post", `{"key": "value"}`).body)
diff --git a/examples/ini/ini.tm b/examples/ini/ini.tm
index cee33f3c..3fa4c834 100644
--- a/examples/ini/ini.tm
+++ b/examples/ini/ini.tm
@@ -10,29 +10,29 @@ _HELP := "
"
func parse_ini(path:Path -> {Text={Text=Text}}):
- text := path:read() or exit("Could not read INI file: $\[31;1]$(path)$\[]")
+ text := path.read() or exit("Could not read INI file: $\[31;1]$(path)$\[]")
sections : @{Text=@{Text=Text}} = @{}
current_section : @{Text=Text} = @{}
# Line wraps:
- text = text:replace_pattern($Pat/\{1 nl}{0+space}/, " ")
+ text = text.replace_pattern($Pat/\{1 nl}{0+space}/, " ")
- for line in text:lines():
- line = line:trim()
- skip if line:starts_with(";") or line:starts_with("#")
- if line:matches_pattern($Pat/[?]/):
- section_name := line:replace($Pat/[?]/, "\1"):trim():lower()
+ for line in text.lines():
+ line = line.trim()
+ skip if line.starts_with(";") or line.starts_with("#")
+ if line.matches_pattern($Pat/[?]/):
+ section_name := line.replace($Pat/[?]/, "\1").trim().lower()
current_section = @{}
sections[section_name] = current_section
- else if line:matches_pattern($Pat/{..}={..}/):
- key := line:replace_pattern($Pat/{..}={..}/, "\1"):trim():lower()
- value := line:replace_pattern($Pat/{..}={..}/, "\2"):trim()
+ else if line.matches_pattern($Pat/{..}={..}/):
+ key := line.replace_pattern($Pat/{..}={..}/, "\1").trim().lower()
+ value := line.replace_pattern($Pat/{..}={..}/, "\2").trim()
current_section[key] = value
return {k=v[] for k,v in sections[]}
func main(path:Path, key:Text?):
- keys := (key or ""):split($|/|)
+ keys := (key or "").split($|/|)
if keys.length > 2:
exit("
Too many arguments!
@@ -44,18 +44,18 @@ func main(path:Path, key:Text?):
say("$data")
return
- section := keys[1]:lower()
+ section := keys[1].lower()
section_data := data[section] or exit("
Invalid section name: $\[31;1]$section$\[]
- Valid names: $\[1]$(", ":join([k:quoted() for k in data.keys]))$\[]
+ Valid names: $\[1]$(", ".join([k.quoted() for k in data.keys]))$\[]
")
if keys.length < 2 or keys[2] == '*':
say("$section_data")
return
- section_key := keys[2]:lower()
+ section_key := keys[2].lower()
value := section_data[section_key] or exit("
Invalid key: $\[31;1]$section_key$\[]
- Valid keys: $\[1]$(", ":join([s:quoted() for s in section_data.keys]))$\[]
+ Valid keys: $\[1]$(", ".join([s.quoted() for s in section_data.keys]))$\[]
")
say(value)
diff --git a/examples/learnxiny.tm b/examples/learnxiny.tm
index ecb1140f..6a3b7e21 100644
--- a/examples/learnxiny.tm
+++ b/examples/learnxiny.tm
@@ -160,18 +160,18 @@ func main():
# Sets are similar to tables, but they represent an unordered collection of
# unique values:
set := {10, 20, 30}
- >> set:has(20)
+ >> set.has(20)
= yes
- >> set:has(999)
+ >> set.has(999)
= no
# You can do some operations on sets:
other_set := {30, 40, 50}
- >> set:with(other_set)
+ >> set.with(other_set)
= {10, 20, 30, 40, 50}
- >> set:without(other_set)
+ >> set.without(other_set)
= {10, 20}
- >> set:overlap(other_set)
+ >> set.overlap(other_set)
= {30}
# So far, the datastructures that have been discussed are all *immutable*,
@@ -184,7 +184,7 @@ func main():
= @[999, 20, 30]
# To call a method, you must use ":" and the name of the method:
- my_arr:sort()
+ my_arr.sort()
>> my_arr
= @[20, 30, 999]
@@ -197,7 +197,7 @@ func main():
# location. Later, a new value might end up there, but the photograph will
# remain unchanged.
snapshot := my_arr[]
- my_arr:insert(1000)
+ my_arr.insert(1000)
>> my_arr
= @[20, 30, 999, 1000]
>> snapshot
@@ -275,7 +275,7 @@ func demo_structs():
= 30
# Calling methods:
- alice:say_age()
+ alice.say_age()
# You can call static methods by using the class name and ".":
>> Person.get_cool_name()
diff --git a/examples/log/log.tm b/examples/log/log.tm
index 3aa45e7a..7375d5f6 100644
--- a/examples/log/log.tm
+++ b/examples/log/log.tm
@@ -13,33 +13,33 @@ func _timestamp(->Text):
strftime(str, 20, "%F %T", tm_info);
str
}
- return c_str:as_text()
+ return c_str.as_text()
func info(text:Text, newline=yes):
say("$\[2]⚫ $text$\[]", newline)
for file in logfiles:
- file:append("$(_timestamp()) [info] $text$\n")
+ file.append("$(_timestamp()) [info] $text$\n")
func debug(text:Text, newline=yes):
say("$\[32]🟢 $text$\[]", newline)
for file in logfiles:
- file:append("$(_timestamp()) [debug] $text$\n")
+ file.append("$(_timestamp()) [debug] $text$\n")
func warn(text:Text, newline=yes):
say("$\[33;1]🟡 $text$\[]", newline)
for file in logfiles:
- file:append("$(_timestamp()) [warn] $text$\n")
+ file.append("$(_timestamp()) [warn] $text$\n")
func error(text:Text, newline=yes):
say("$\[31;1]🔴 $text$\[]", newline)
for file in logfiles:
- file:append("$(_timestamp()) [error] $text$\n")
+ file.append("$(_timestamp()) [error] $text$\n")
func add_logfile(file:Path):
- logfiles:add(file)
+ logfiles.add(file)
func remove_logfile(file:Path):
- logfiles:remove(file)
+ logfiles.remove(file)
func main():
add_logfile((./log.txt))
diff --git a/examples/patterns/README.md b/examples/patterns/README.md
index 9e9d8601..8e2a1ff8 100644
--- a/examples/patterns/README.md
+++ b/examples/patterns/README.md
@@ -123,7 +123,7 @@ be automatically escaped using the `{1 ?}` rule described above:
# This is: `{ 1{ }` (one open brace) followed by the literal text "..xxx}"
# No error:
->> some_text:find($/$user_input/)
+>> some_text.find($/$user_input/)
= 0
```
@@ -168,7 +168,7 @@ An iterator function that yields `PatternMatch` objects one at a time.
**Example:**
```tomo
text := "one, two, three"
-for word in text:by_pattern($Pat"{id}"):
+for word in text.by_pattern($Pat"{id}"):
say(word.text)
```
@@ -190,7 +190,7 @@ An iterator function that yields text segments.
**Example:**
```tomo
text := "one two three"
-for word in text:by_pattern_split($Pat"{whitespace}"):
+for word in text.by_pattern_split($Pat"{whitespace}"):
say(word.text)
```
@@ -211,7 +211,7 @@ func each_pattern(text:Text, pattern:Pat, fn:func(m:PatternMatch), recursive=yes
**Example:**
```tomo
text := "one two three"
-text:each_pattern($Pat"{id}", func(m:PatternMatch):
+text.each_pattern($Pat"{id}", func(m:PatternMatch):
say(m.txt)
)
```
@@ -234,7 +234,7 @@ An array of `PatternMatch` objects.
**Example:**
```tomo
text := "one! two three!"
->> text:find_patterns($Pat"{id}!")
+>> text.find_patterns($Pat"{id}!")
= [PatternMatch(text="one!", index=1, captures=["one"]), PatternMatch(text="three!", index=10, captures=["three"])]
```
@@ -256,7 +256,7 @@ func has_pattern(text:Text, pattern:Pat -> Bool)
**Example:**
```tomo
text := "...okay..."
->> text:has_pattern($Pat"{id}")
+>> text.has_pattern($Pat"{id}")
= yes
```
@@ -281,7 +281,7 @@ A new text with the transformed matches.
```tomo
text := "I have #apples and #oranges and #plums"
fruits := {"apples"=4, "oranges"=5}
->> text:map_pattern($Pat'#{id}', func(match:PatternMatch):
+>> text.map_pattern($Pat'#{id}', func(match:PatternMatch):
fruit := match.captures[1]
"$(fruits[fruit] or 0) $fruit"
)
@@ -305,9 +305,9 @@ func matches_pattern(text:Text, pattern:Pat -> Bool)
**Example:**
```tomo
->> "Hello!!!":matches_pattern($Pat"{id}")
+>> "Hello!!!".matches_pattern($Pat"{id}")
= no
->> "Hello":matches_pattern($Pat"{id}")
+>> "Hello".matches_pattern($Pat"{id}")
= yes
```
@@ -329,9 +329,9 @@ not match the pattern.
**Example:**
```tomo
->> "123 boxes":pattern_captures($Pat"{int} {id}")
+>> "123 boxes".pattern_captures($Pat"{int} {id}")
= ["123", "boxes"]?
->> "xxx":pattern_captures($Pat"{int} {id}")
+>> "xxx".pattern_captures($Pat"{int} {id}")
= none
```
@@ -355,19 +355,19 @@ A new text with replacements applied.
**Example:**
```tomo
->> "I have 123 apples and 456 oranges":replace_pattern($Pat"{int}", "some")
+>> "I have 123 apples and 456 oranges".replace_pattern($Pat"{int}", "some")
= "I have some apples and some oranges"
->> "I have 123 apples and 456 oranges":replace_pattern($Pat"{int}", "(@1)")
+>> "I have 123 apples and 456 oranges".replace_pattern($Pat"{int}", "(@1)")
= "I have (123) apples and (456) oranges"
->> "I have 123 apples and 456 oranges":replace_pattern($Pat"{int}", "(?1)", backref="?")
+>> "I have 123 apples and 456 oranges".replace_pattern($Pat"{int}", "(?1)", backref="?")
= "I have (123) apples and (456) oranges"
->> "bad(fn(), bad(notbad))":replace_pattern($Pat"bad(?)", "good(@1)")
+>> "bad(fn(), bad(notbad))".replace_pattern($Pat"bad(?)", "good(@1)")
= "good(fn(), good(notbad))"
->> "bad(fn(), bad(notbad))":replace_pattern($Pat"bad(?)", "good(@1)", recursive=no)
+>> "bad(fn(), bad(notbad))".replace_pattern($Pat"bad(?)", "good(@1)", recursive=no)
= "good(fn(), bad(notbad))"
```
@@ -388,7 +388,7 @@ An array of text segments.
**Example:**
```tomo
->> "one two three":split_pattern($Pat"{whitespace}")
+>> "one two three".split_pattern($Pat"{whitespace}")
= ["one", "two", "three"]
```
@@ -412,7 +412,7 @@ A new text with all specified replacements applied.
**Example:**
```tomo
>> text := "foo(x, baz(1))"
->> text:translate_patterns({
+>> text.translate_patterns({
$Pat"{id}(?)"="call(fn('@1'), @2)",
$Pat"{id}"="var('@1')",
$Pat"{int}"="int(@1)",
@@ -439,6 +439,6 @@ The trimmed text.
**Example:**
```tomo
->> "123abc456":trim_pattern($Pat"{digit}")
+>> "123abc456".trim_pattern($Pat"{digit}")
= "abc"
```
diff --git a/examples/pthreads/pthreads.tm b/examples/pthreads/pthreads.tm
index fb79e822..3be052b4 100644
--- a/examples/pthreads/pthreads.tm
+++ b/examples/pthreads/pthreads.tm
@@ -69,18 +69,18 @@ struct IntQueue(_queue:@[Int], _mutex:@pthread_mutex_t, _cond:@pthread_cond_t):
return IntQueue(@initial, pthread_mutex_t.new(), pthread_cond_t.new())
func give(q:IntQueue, n:Int):
- do: q._mutex:lock()
- q._queue:insert(n)
- q._mutex:unlock()
- q._cond:signal()
+ do: q._mutex.lock()
+ q._queue.insert(n)
+ q._mutex.unlock()
+ q._cond.signal()
func take(q:IntQueue -> Int):
- do: q._mutex:lock()
- n := q._queue:pop(1)
+ do: q._mutex.lock()
+ n := q._queue.pop(1)
while not n:
- q._cond:wait(q._mutex)
- n = q._queue:pop(1)
- q._mutex:unlock()
+ q._cond.wait(q._mutex)
+ n = q._queue.pop(1)
+ q._mutex.unlock()
return n!
fail("Unreachable")
@@ -90,29 +90,29 @@ func main():
say_mutex := pthread_mutex_t.new()
announce := func(speaker:Text, text:Text):
- do: say_mutex:lock()
+ do: say_mutex.lock()
say("$\033[2m[$speaker]$\033[m $text")
- say_mutex:unlock()
+ say_mutex.unlock()
worker := pthread_t.new(func():
say("I'm in the thread!")
repeat:
announce("worker", "waiting for job")
- job := jobs:take()
+ job := jobs.take()
result := job * 10
announce("worker", "Jobbing $job into $result")
- results:give(result)
+ results.give(result)
announce("worker", "Signaled $result")
)
for i in 10:
announce("boss", "Pushing job $i")
- jobs:give(i)
+ jobs.give(i)
announce("boss", "Gave job $i")
for i in 10:
announce("boss", "Getting result...")
- result := results:take()
+ result := results.take()
announce("boss", "Got result $result")
- >> worker:cancel()
+ >> worker.cancel()
diff --git a/examples/random/README.md b/examples/random/README.md
index 6233c1ba..d9983ab7 100644
--- a/examples/random/README.md
+++ b/examples/random/README.md
@@ -17,14 +17,14 @@ a Tomo program launches.
This documentation provides details on RNG functions available in the API.
Arrays also have some methods which use RNG values:
-`array:shuffle()`, `array:shuffled()`, `array:random()`, and `array:sample()`.
+`array.shuffle()`, `array.shuffled()`, `array.random()`, and `array.sample()`.
- [`func bool(rng: RNG, p: Num = 0.5 -> Bool)`](#bool)
- [`func byte(rng: RNG -> Byte)`](#byte)
- [`func bytes(rng: RNG, count: Int -> [Byte])`](#bytes)
- [`func copy(rng: RNG -> RNG)`](#copy)
- [`func int(rng: RNG, min: Int, max: Int -> Int)`](#int`, `int64`, `int32`, `int16`, `int8)
-- [`func new(seed: [Byte] = (/dev/urandom):read_bytes(40)! -> RNG)`](#new)
+- [`func new(seed: [Byte] = (/dev/urandom).read_bytes(40)! -> RNG)`](#new)
- [`func num(rng: RNG, min: Num = 0.0, max: Num = 1.0 -> Num)`](#num`, `num32)
-------------
@@ -46,9 +46,9 @@ func bool(rng: RNG, p: Num = 0.5 -> Bool)
**Example:**
```tomo
->> random:bool()
+>> random.bool()
= no
->> random:bool(1.0)
+>> random.bool(1.0)
= yes
```
@@ -68,7 +68,7 @@ A random byte (0-255).
**Example:**
```tomo
->> random:byte()
+>> random.byte()
= 103[B]
```
@@ -89,7 +89,7 @@ An array of length `count` random bytes with uniform random distribution (0-255)
**Example:**
```tomo
->> random:bytes(4)
+>> random.bytes(4)
= [135[B], 169[B], 103[B], 212[B]]
```
@@ -111,13 +111,13 @@ A copy of the given RNG.
**Example:**
```tomo
>> rng := RNG.new([])
->> copy := rng:copy()
+>> copy := rng.copy()
->> rng:bytes(10)
+>> rng.bytes(10)
= [224[B], 102[B], 190[B], 59[B], 251[B], 50[B], 217[B], 170[B], 15[B], 221[B]]
# The copy runs in parallel to the original RNG:
->> copy:bytes(10)
+>> copy.bytes(10)
= [224[B], 102[B], 190[B], 59[B], 251[B], 50[B], 217[B], 170[B], 15[B], 221[B]]
```
@@ -144,7 +144,7 @@ is greater than `max`, an error will be raised.
**Example:**
```tomo
->> random:int(1, 10)
+>> random.int(1, 10)
= 8
```
@@ -154,7 +154,7 @@ is greater than `max`, an error will be raised.
Return a new random number generator.
```tomo
-func new(seed: [Byte] = (/dev/urandom):read_bytes(40)! -> RNG)
+func new(seed: [Byte] = (/dev/urandom).read_bytes(40)! -> RNG)
```
- `seed`: The seed use for the random number generator. A seed length of 40
@@ -167,7 +167,7 @@ A new random number generator.
**Example:**
```tomo
>> my_rng := RNG.new([1[B], 2[B], 3[B], 4[B]])
->> my_rng:bool()
+>> my_rng.bool()
= yes
```
@@ -191,6 +191,6 @@ A floating point number uniformly chosen from the range `[min, max]`
**Example:**
```tomo
->> random:num(1, 10)
+>> random.num(1, 10)
= 9.512830439975572
```
diff --git a/examples/random/random.tm b/examples/random/random.tm
index 95d2f9fe..1f60aff0 100644
--- a/examples/random/random.tm
+++ b/examples/random/random.tm
@@ -79,9 +79,9 @@ struct RandomNumberGenerator(_chacha:chacha_ctx, _random_bytes:[Byte]=[]; secret
func bool(rng:&RandomNumberGenerator, probability=0.5 -> Bool):
if probability == 0.5:
- return rng:byte() < 0x80
+ return rng.byte() < 0x80
else:
- return rng:num(0., 1.) < 0.5
+ return rng.num(0., 1.) < 0.5
func int64(rng:&RandomNumberGenerator, min=Int64.min, max=Int64.max -> Int64):
fail("Random minimum value $min is larger than the maximum value $max") if min > max
@@ -188,7 +188,7 @@ struct RandomNumberGenerator(_chacha:chacha_ctx, _random_bytes:[Byte]=[]; secret
}
func num32(rng:&RandomNumberGenerator, min=Num32(0.), max=Num32(1.) -> Num32):
- return Num32(rng:num(Num(min), Num(max)))
+ return Num32(rng.num(Num(min), Num(max)))
func int(rng:&RandomNumberGenerator, min:Int, max:Int -> Int):
return inline C : Int {
@@ -228,13 +228,13 @@ struct RandomNumberGenerator(_chacha:chacha_ctx, _random_bytes:[Byte]=[]; secret
func main():
>> rng := RandomNumberGenerator.new()
- >> rng:num()
- >> rng:num()
- >> rng:num()
- >> rng:num(0, 100)
- >> rng:byte()
- >> rng:bytes(20)
- # >> rng:int(1, 100)
- # >> rng:int(1, 100)
- # >> rng:int(1, 100)
- # >> rng:int(1, 100)
+ >> rng.num()
+ >> rng.num()
+ >> rng.num()
+ >> rng.num(0, 100)
+ >> rng.byte()
+ >> rng.bytes(20)
+ # >> rng.int(1, 100)
+ # >> rng.int(1, 100)
+ # >> rng.int(1, 100)
+ # >> rng.int(1, 100)
diff --git a/examples/shell/shell.tm b/examples/shell/shell.tm
index dd26428f..816d63a2 100644
--- a/examples/shell/shell.tm
+++ b/examples/shell/shell.tm
@@ -2,16 +2,16 @@ use commands
lang Shell:
convert(text:Text -> Shell):
- return Shell.from_text("'" ++ text:replace($/'/, `'"'"'`) ++ "'")
+ return Shell.from_text("'" ++ text.replace($/'/, `'"'"'`) ++ "'")
convert(texts:[Text] -> Shell):
- return Shell.from_text(" ":join([Shell(t).text for t in texts]))
+ return Shell.from_text(" ".join([Shell(t).text for t in texts]))
convert(path:Path -> Shell):
- return Shell(Text(path:expand_home()))
+ return Shell(Text(path.expand_home()))
convert(paths:[Path] -> Shell):
- return Shell.from_text(" ":join([Shell(Text(p)).text for p in paths]))
+ return Shell.from_text(" ".join([Shell(Text(p)).text for p in paths]))
convert(n:Int -> Shell): return Shell.from_text(Text(n))
convert(n:Int64 -> Shell): return Shell.from_text(Text(n))
@@ -25,20 +25,20 @@ lang Shell:
return Command("sh", ["-c", shell.text])
func result(shell:Shell, input="", input_bytes:[Byte]=[] -> ProgramResult):
- return shell:command():result(input=input, input_bytes=input_bytes)
+ return shell.command().result(input=input, input_bytes=input_bytes)
func run(shell:Shell -> ExitType):
- return shell:command():run()
+ return shell.command().run()
func get_output(shell:Shell, input="", trim_newline=yes -> Text?):
- return shell:command():get_output(input=input, trim_newline=trim_newline)
+ return shell.command().get_output(input=input, trim_newline=trim_newline)
func get_output_bytes(shell:Shell, input="", input_bytes:[Byte]=[] -> [Byte]?):
- return shell:command():get_output_bytes(input=input, input_bytes=input_bytes)
+ return shell.command().get_output_bytes(input=input, input_bytes=input_bytes)
func by_line(shell:Shell -> func(->Text?)?):
- return shell:command():by_line()
+ return shell.command().by_line()
func main(command:Shell):
- for line in command:by_line()!:
+ for line in command.by_line()!:
>> line
diff --git a/examples/time/time.tm b/examples/time/time.tm
index 8664f2e4..4d686ac7 100644
--- a/examples/time/time.tm
+++ b/examples/time/time.tm
@@ -77,10 +77,10 @@ struct Time(tv_sec:Int64, tv_usec:Int64; extern):
return seconds
func minutes_till(t:Time, target:Time -> Num):
- return t:seconds_till(target)/60.
+ return t.seconds_till(target)/60.
func hours_till(t:Time, target:Time -> Num):
- return t:seconds_till(target)/3600.
+ return t.seconds_till(target)/3600.
func relative(t:Time, relative_to=Time.now(), timezone=Time.local_timezone() -> Text):
inline C {
@@ -116,17 +116,17 @@ struct Time(tv_sec:Int64, tv_usec:Int64; extern):
func time(t:Time, seconds=no, am_pm=yes, timezone=Time.local_timezone() -> Text):
time := if seconds and am_pm:
- t:format("%l:%M:%S%P")
+ t.format("%l:%M:%S%P")
else if seconds and not am_pm:
- t:format("%T")
+ t.format("%T")
else if not seconds and am_pm:
- t:format("%l:%M%P")
+ t.format("%l:%M%P")
else:
- t:format("%H:%M")
- return time:trim()
+ t.format("%H:%M")
+ return time.trim()
func date(t:Time, timezone=Time.local_timezone() -> Text):
- return t:format("%F")
+ return t.format("%F")
func info(t:Time, timezone=Time.local_timezone() -> TimeInfo):
return inline C : TimeInfo {
@@ -185,23 +185,23 @@ struct Time(tv_sec:Int64, tv_usec:Int64; extern):
}
func _run_tests():
- >> Time.now():format()
+ >> Time.now().format()
>> Time.set_local_timezone("Europe/Paris")
- >> Time.now():format()
+ >> Time.now().format()
>> Time.set_local_timezone("America/New_York")
- >> Time.now():format()
- # >> Time.now():format(timezone="Europe/Paris")
- # >> Time.now():format()
- # >> Time.now():format("%Y-%m-%d")
- # >> Time.new(2023, 11, 5):format()
+ >> Time.now().format()
+ # >> Time.now().format(timezone="Europe/Paris")
+ # >> Time.now().format()
+ # >> Time.now().format("%Y-%m-%d")
+ # >> Time.new(2023, 11, 5).format()
# >> Time.local_timezone()
- # >> Time.new(2023, 11, 5):seconds_till(Time.now())
- # >> Time.new(2023, 11, 5):relative()
+ # >> Time.new(2023, 11, 5).seconds_till(Time.now())
+ # >> Time.new(2023, 11, 5).relative()
- # >> Time.now():info()
- # >> Time.now():time()
- # >> Time.now():date()
+ # >> Time.now().info()
+ # >> Time.now().time()
+ # >> Time.now().date()
# >> Time.parse("2023-11-05 01:01", "%Y-%m-%d %H:%M")
# >> Time.parse("2023-11-05 01:01", "%Y-%m-%d %H:%M", timezone="Europe/Paris")
diff --git a/examples/tomo-install/tomo-install.tm b/examples/tomo-install/tomo-install.tm
index 0be05619..0a255987 100644
--- a/examples/tomo-install/tomo-install.tm
+++ b/examples/tomo-install/tomo-install.tm
@@ -12,13 +12,13 @@ _HELP := "
func find_urls(path:Path -> [Text]):
urls : @[Text] = @[]
- if path:is_directory():
- for f in path:children():
- urls:insert_all(find_urls(f))
- else if path:is_file() and path:extension() == ".tm":
- for line in path:by_line()!:
- if captures := line:pattern_captures($Pat/use{space}{url}/) or line:pattern_captures($Pat/{id}{space}:={space}use{space}{url}/):
- urls:insert(captures[-1])
+ if path.is_directory():
+ for f in path.children():
+ urls.insert_all(find_urls(f))
+ else if path.is_file() and path.extension() == ".tm":
+ for line in path.by_line()!:
+ if captures := line.pattern_captures($Pat/use{space}{url}/) or line.pattern_captures($Pat/{id}{space}:={space}use{space}{url}/):
+ urls.insert(captures[-1])
return urls
func main(paths:[Path]):
@@ -27,27 +27,27 @@ func main(paths:[Path]):
urls := (++: find_urls(p) for p in paths) or []
- github_token := (~/.config/tomo/github-token):read()
+ github_token := (~/.config/tomo/github-token).read()
- (~/.local/share/tomo/installed):create_directory()
- (~/.local/share/tomo/lib):create_directory()
+ (~/.local/share/tomo/installed).create_directory()
+ (~/.local/share/tomo/lib).create_directory()
for url in urls:
original_url := url
- url_without_protocol := url:trim_pattern($Pat"http{0-1 s}://", right=no)
- hash := $Shell@(echo -n @url_without_protocol | sha256sum):get_output()!:slice(to=32)
- if (~/.local/share/tomo/installed/$hash):is_directory():
+ url_without_protocol := url.trim_pattern($Pat"http{0-1 s}://", right=no)
+ hash := $Shell@(echo -n @url_without_protocol | sha256sum).get_output()!.slice(to=32)
+ if (~/.local/share/tomo/installed/$hash).is_directory():
say("Already installed: $url")
skip
alias : Text? = none
curl_flags := ["-L"]
- if github := url_without_protocol:pattern_captures($Pat"github.com/{!/}/{!/}#{..}"):
+ if github := url_without_protocol.pattern_captures($Pat"github.com/{!/}/{!/}#{..}"):
user := github[1]
repo := github[2]
tag := github[3]
url = "https://api.github.com/repos/$user/$repo/tarball/$tag"
- alias = "$(repo:without_prefix("tomo-")).$(tag).$(user)"
+ alias = "$(repo.without_prefix("tomo-")).$(tag).$(user)"
if github_token:
curl_flags ++= ["-H", "Authorization: Bearer $github_token"]
curl_flags ++= [
@@ -55,7 +55,7 @@ func main(paths:[Path]):
"-H", "X-GitHub-Api-Version: 2022-11-28",
]
- (~/.local/share/tomo/downloads/$hash):create_directory()
+ (~/.local/share/tomo/downloads/$hash).create_directory()
say($Shell@`
set -euo pipefail
cd ~/.local/share/tomo/downloads/@hash
@@ -67,7 +67,7 @@ func main(paths:[Path]):
else
ln -f -s ../installed/@hash/lib@hash.so ~/.local/share/tomo/lib/lib@hash.so
fi
- `:get_output()!)
+ `.get_output()!)
if alias:
say($Shell(
@@ -78,7 +78,7 @@ func main(paths:[Path]):
else
ln -f -s lib@hash.so ~/.local/share/tomo/lib/lib@alias.so
fi
- ):get_output()!)
+ ).get_output()!)
say("$\[1]Installed $url!$\[]")
diff --git a/examples/tomodeps/tomodeps.tm b/examples/tomodeps/tomodeps.tm
index c6c2171e..dd7bec10 100644
--- a/examples/tomodeps/tomodeps.tm
+++ b/examples/tomodeps/tomodeps.tm
@@ -12,44 +12,44 @@ _HELP := "
enum Dependency(File(path:Path), Module(name:Text))
func _get_file_dependencies(file:Path -> {Dependency}):
- if not file:is_file():
+ if not file.is_file():
say("Could not read file: $file")
- return {}
+ return {/}
- deps : @{Dependency} = @{}
- if lines := file:by_line():
+ deps : @{Dependency} = @{/}
+ if lines := file.by_line():
for line in lines:
- if line:matches_pattern($Pat/use {..}.tm/):
- file_import := Path.from_text(line:replace_pattern($Pat/use {..}/, "\1")):resolved(relative_to=file)
- deps:add(Dependency.File(file_import))
- else if line:matches_pattern($Pat/use {id}/):
- module_name := line:replace_pattern($Pat/use {..}/, "\1")
- deps:add(Dependency.Module(module_name))
+ if line.matches_pattern($Pat/use {..}.tm/):
+ file_import := Path.from_text(line.replace_pattern($Pat/use {..}/, "\1")).resolved(relative_to=file)
+ deps.add(Dependency.File(file_import))
+ else if line.matches_pattern($Pat/use {id}/):
+ module_name := line.replace_pattern($Pat/use {..}/, "\1")
+ deps.add(Dependency.Module(module_name))
return deps[]
func _build_dependency_graph(dep:Dependency, dependencies:@{Dependency={Dependency}}):
- return if dependencies:has(dep)
+ return if dependencies.has(dep)
- dependencies[dep] = {} # Placeholder
+ dependencies[dep] = {/} # Placeholder
dep_deps := when dep is File(path):
_get_file_dependencies(path)
is Module(module):
dir := (~/.local/share/tomo/installed/$module)
- module_deps : @{Dependency} = @{}
- visited : @{Path} = @{}
- unvisited := @{f:resolved() for f in dir:files() if f:extension() == ".tm"}
+ module_deps : @{Dependency} = @{/}
+ visited : @{Path} = @{/}
+ unvisited := @{f.resolved() for f in dir.files() if f.extension() == ".tm"}
while unvisited.length > 0:
file := unvisited.items[-1]
- unvisited:remove(file)
- visited:add(file)
+ unvisited.remove(file)
+ visited.add(file)
for file_dep in _get_file_dependencies(file):
when file_dep is File(f):
- if not visited:has(f):
- unvisited:add(f)
+ if not visited.has(f):
+ unvisited.add(f)
is Module(m):
- module_deps:add(file_dep)
+ module_deps.add(file_dep)
module_deps[]
dependencies[dep] = dep_deps
@@ -66,19 +66,19 @@ func _printable_name(dep:Dependency -> Text):
when dep is Module(module):
return "$(\x1b)[34;1m$module$(\x1b)[m"
is File(f):
- f = f:relative_to((.))
- if f:exists():
+ f = f.relative_to((.))
+ if f.exists():
return Text(f)
else:
return "$(\x1b)[31;1m$(f) (not found)$(\x1b)[m"
func _draw_tree(dep:Dependency, dependencies:{Dependency={Dependency}}, already_printed:@{Dependency}, prefix="", is_last=yes):
- if already_printed:has(dep):
+ if already_printed.has(dep):
say(prefix ++ (if is_last: "└── " else: "├── ") ++ _printable_name(dep) ++ " $\x1b[2m(recursive)$\x1b[m")
return
say(prefix ++ (if is_last: "└── " else: "├── ") ++ _printable_name(dep))
- already_printed:add(dep)
+ already_printed.add(dep)
child_prefix := prefix ++ (if is_last: " " else: "│ ")
@@ -88,9 +88,9 @@ func _draw_tree(dep:Dependency, dependencies:{Dependency={Dependency}}, already_
_draw_tree(child, dependencies, already_printed, child_prefix, is_child_last)
func draw_tree(dep:Dependency, dependencies:{Dependency={Dependency}}):
- printed : @{Dependency} = @{}
+ printed : @{Dependency} = @{/}
say(_printable_name(dep))
- printed:add(dep)
+ printed.add(dep)
deps := dependencies[dep] or {/}
for i,child in deps.items:
is_child_last := (i == deps.length)
@@ -104,11 +104,11 @@ func main(files:[Text]):
")
for arg in files:
- if arg:matches_pattern($Pat/{..}.tm/):
- path := Path.from_text(arg):resolved()
+ if arg.matches_pattern($Pat/{..}.tm/):
+ path := Path.from_text(arg).resolved()
dependencies := get_dependency_graph(File(path))
draw_tree(File(path), dependencies)
- else if arg:matches_pattern($Pat/{id}/):
+ else if arg.matches_pattern($Pat/{id}/):
dependencies := get_dependency_graph(Module(arg))
draw_tree(Module(arg), dependencies)
else:
diff --git a/examples/vectors/vectors.tm b/examples/vectors/vectors.tm
index f978d3d1..42ada614 100644
--- a/examples/vectors/vectors.tm
+++ b/examples/vectors/vectors.tm
@@ -19,24 +19,24 @@ struct Vec2(x,y:Num):
func divided_by(v:Vec2, divisor:Num->Vec2; inline):
return Vec2(v.x/divisor, v.y/divisor)
func length(v:Vec2->Num; inline):
- return (v.x*v.x + v.y*v.y):sqrt()
+ return (v.x*v.x + v.y*v.y).sqrt()
func dist(a,b:Vec2->Num; inline):
- return a:minus(b):length()
+ return a.minus(b).length()
func angle(v:Vec2->Num; inline):
return Num.atan2(v.y, v.x)
func norm(v:Vec2->Vec2; inline):
if v.x == 0 and v.y == 0:
return v
- len := v:length()
+ len := v.length()
return Vec2(v.x/len, v.y/len)
func rotated(v:Vec2, radians:Num -> Vec2):
- cos := radians:cos() or return v
- sin := radians:sin() or return v
+ cos := radians.cos() or return v
+ sin := radians.sin() or return v
return Vec2(cos*v.x - sin*v.y, sin*v.x + cos*v.y)
func mix(a,b:Vec2, amount:Num -> Vec2):
return Vec2(
- amount:mix(a.x, b.x),
- amount:mix(a.y, b.y),
+ amount.mix(a.x, b.x),
+ amount.mix(a.y, b.y),
)
struct Vec3(x,y,z:Num):
@@ -58,19 +58,19 @@ struct Vec3(x,y,z:Num):
func divided_by(v:Vec3, divisor:Num->Vec3; inline):
return Vec3(v.x/divisor, v.y/divisor, v.z/divisor)
func length(v:Vec3->Num; inline):
- return (v.x*v.x + v.y*v.y + v.z*v.z):sqrt()
+ return (v.x*v.x + v.y*v.y + v.z*v.z).sqrt()
func dist(a,b:Vec3->Num; inline):
- return a:minus(b):length()
+ return a.minus(b).length()
func norm(v:Vec3->Vec3; inline):
if v.x == 0 and v.y == 0 and v.z == 0:
return v
- len := v:length()
+ len := v.length()
return Vec3(v.x/len, v.y/len, v.z/len)
func mix(a,b:Vec3, amount:Num -> Vec3):
return Vec3(
- amount:mix(a.x, b.x),
- amount:mix(a.y, b.y),
- amount:mix(a.z, b.z),
+ amount.mix(a.x, b.x),
+ amount.mix(a.y, b.y),
+ amount.mix(a.z, b.z),
)
@@ -97,7 +97,7 @@ struct IVec2(x,y:Int):
y := Num(v.y)
return Num.sqrt(x*x + y*y)
func dist(a,b:IVec2->Num; inline):
- return a:minus(b):length()
+ return a.minus(b).length()
func angle(v:IVec2->Num; inline):
return Num.atan2(Num(v.y), Num(v.x))
@@ -125,7 +125,7 @@ struct IVec3(x,y,z:Int):
z := Num(v.z)
return Num.sqrt(x*x + y*y + z*z)
func dist(a,b:IVec3->Num; inline):
- return a:minus(b):length()
+ return a.minus(b).length()
func main():
>> Vec2(10, 20)
diff --git a/examples/wrap/wrap.tm b/examples/wrap/wrap.tm
index 61ca5821..448ab813 100644
--- a/examples/wrap/wrap.tm
+++ b/examples/wrap/wrap.tm
@@ -15,11 +15,11 @@ UNICODE_HYPHEN := \{hyphen}
func unwrap(text:Text, preserve_paragraphs=yes, hyphen=UNICODE_HYPHEN -> Text):
if preserve_paragraphs:
- paragraphs := text:split($/{2+ nl}/)
+ paragraphs := text.split($/{2+ nl}/)
if paragraphs.length > 1:
- return \n\n:join([unwrap(p, hyphen=hyphen, preserve_paragraphs=no) for p in paragraphs])
+ return \n\n.join([unwrap(p, hyphen=hyphen, preserve_paragraphs=no) for p in paragraphs])
- return text:replace($/$(hyphen)$(\n)/, "")
+ return text.replace($/$(hyphen)$(\n)/, "")
func wrap(text:Text, width:Int, min_split=3, hyphen="-" -> Text):
if width <= 0:
@@ -35,8 +35,8 @@ func wrap(text:Text, width:Int, min_split=3, hyphen="-" -> Text):
lines : @[Text] = @[]
line := ""
- for word in text:split($/{whitespace}/):
- letters := word:split()
+ for word in text.split($/{whitespace}/):
+ letters := word.split()
skip if letters.length == 0
while not _can_fit_word(line, letters, width):
@@ -49,17 +49,17 @@ func wrap(text:Text, width:Int, min_split=3, hyphen="-" -> Text):
split = split _max_ min_split
split = split _min_ (letters.length - min_split)
if line != "": line ++= " "
- line ++= ((++: letters:to(split)) or "") ++ hyphen
- letters = letters:from(split + 1)
+ line ++= ((++: letters.to(split)) or "") ++ hyphen
+ letters = letters.from(split + 1)
else if line == "":
# Force split word without hyphenation:
if line != "": line ++= " "
- line ++= (++: letters:to(line_space)) or ""
- letters = letters:from(line_space + 1)
+ line ++= (++: letters.to(line_space)) or ""
+ letters = letters.from(line_space + 1)
else:
pass # Move to next line
- lines:insert(line)
+ lines.insert(line)
line = ""
if letters.length > 0:
@@ -67,9 +67,9 @@ func wrap(text:Text, width:Int, min_split=3, hyphen="-" -> Text):
line ++= (++: letters) or ""
if line != "":
- lines:insert(line)
+ lines.insert(line)
- return \n:join(lines)
+ return \n.join(lines)
func _can_fit_word(line:Text, letters:[Text], width:Int -> Bool; inline):
if line == "":
@@ -82,21 +82,21 @@ func main(files:[Path], width=80, inplace=no, min_split=3, rewrap=yes, hyphen=UN
files = [(/dev/stdin)]
for file in files:
- text := file:read() or exit("Could not read file: $file")
+ text := file.read() or exit("Could not read file: $file")
if rewrap:
text = unwrap(text)
- out := if file:is_file() and inplace:
+ out := if file.is_file() and inplace:
file
else:
(/dev/stdout)
first := yes
wrapped_paragraphs : @[Text] = @[]
- for paragraph in text:split($/{2+ nl}/):
- wrapped_paragraphs:insert(
+ for paragraph in text.split($/{2+ nl}/):
+ wrapped_paragraphs.insert(
wrap(paragraph, width=width, min_split=min_split, hyphen=hyphen)
)
- out:write(\n\n:join(wrapped_paragraphs[]) ++ \n)
+ out.write(\n\n.join(wrapped_paragraphs[]) ++ \n)