feat: add pexpect and yaml modules with jinja from-import support
Add new pexpect module for process spawning and interaction, including Spawn class with expect, sendline, and timeout handling. Introduce yaml module for YAML parsing with support for nested structures, lists, and data types. Extend jinja template engine with brace tokenization and FromImportNode for macro imports across templates. Register all new foreign functions in modules.c and include generated demo scripts.
This commit is contained in:
Vendored
+19
@@ -0,0 +1,19 @@
|
||||
// retoor <retoor@molodetz.nl>
|
||||
|
||||
import "jinja" for Environment, DictLoader, ChoiceLoader
|
||||
|
||||
var loader1 = DictLoader.new({"a.html": "Template A"})
|
||||
var loader2 = DictLoader.new({"b.html": "Template B"})
|
||||
var choice = ChoiceLoader.new([loader1, loader2])
|
||||
|
||||
System.print(choice.exists("a.html")) // expect: true
|
||||
System.print(choice.exists("b.html")) // expect: true
|
||||
System.print(choice.exists("c.html")) // expect: false
|
||||
System.print(choice.getSource("a.html")) // expect: Template A
|
||||
System.print(choice.getSource("b.html")) // expect: Template B
|
||||
|
||||
var env = Environment.new(choice)
|
||||
var tplA = env.getTemplate("a.html")
|
||||
var tplB = env.getTemplate("b.html")
|
||||
System.print(tplA.render({})) // expect: Template A
|
||||
System.print(tplB.render({})) // expect: Template B
|
||||
Vendored
+24
@@ -0,0 +1,24 @@
|
||||
// retoor <retoor@molodetz.nl>
|
||||
|
||||
import "jinja" for Environment, DictLoader
|
||||
|
||||
var tpl1 = "{\x25 set data = {\"name\": \"Alice\", \"age\": 30} \x25}Name: {{ data.name }}, Age: {{ data.age }}"
|
||||
var tpl2 = "{\x25 set empty = {} \x25}Done"
|
||||
var tpl3 = "{\x25 set single = {\"key\": \"value\"} \x25}Key: {{ single.key }}"
|
||||
|
||||
var loader = DictLoader.new({
|
||||
"tpl1.html": tpl1,
|
||||
"tpl2.html": tpl2,
|
||||
"tpl3.html": tpl3
|
||||
})
|
||||
|
||||
var env = Environment.new(loader)
|
||||
|
||||
var result1 = env.getTemplate("tpl1.html").render({})
|
||||
System.print(result1) // expect: Name: Alice, Age: 30
|
||||
|
||||
var result2 = env.getTemplate("tpl2.html").render({})
|
||||
System.print(result2) // expect: Done
|
||||
|
||||
var result3 = env.getTemplate("tpl3.html").render({})
|
||||
System.print(result3) // expect: Key: value
|
||||
Vendored
+15
@@ -0,0 +1,15 @@
|
||||
// retoor <retoor@molodetz.nl>
|
||||
// nontest
|
||||
|
||||
import "pexpect" for Spawn
|
||||
import "timer" for Timer
|
||||
|
||||
System.print("Creating child")
|
||||
var child = Spawn.new("echo test")
|
||||
System.print("Child created, pid: %(child.pid)")
|
||||
System.print("isalive: %(child.isalive)")
|
||||
Timer.sleep(500)
|
||||
System.print("After sleep, isalive: %(child.isalive)")
|
||||
System.print("buffer: [%(child.buffer)]")
|
||||
child.close()
|
||||
System.print("Done")
|
||||
Vendored
+21
@@ -0,0 +1,21 @@
|
||||
// retoor <retoor@molodetz.nl>
|
||||
|
||||
import "pexpect" for Spawn, Pexpect
|
||||
|
||||
var child = Spawn.new("echo 'hello world'")
|
||||
var result = child.expect(["world", "hello"])
|
||||
System.print(result) // expect: 1
|
||||
System.print(child.after) // expect: hello
|
||||
child.close()
|
||||
|
||||
child = Spawn.new("printf 'abc123def'")
|
||||
result = child.expectExact(["123"])
|
||||
System.print(result) // expect: 0
|
||||
System.print(child.before) // expect: abc
|
||||
System.print(child.after) // expect: 123
|
||||
child.close()
|
||||
|
||||
child = Spawn.new("echo 'test multiple patterns'")
|
||||
result = child.expect(["foo", "bar", "multiple"])
|
||||
System.print(result) // expect: 2
|
||||
child.close()
|
||||
Vendored
+16
@@ -0,0 +1,16 @@
|
||||
// retoor <retoor@molodetz.nl>
|
||||
|
||||
import "pexpect" for Spawn, Pexpect
|
||||
|
||||
var child = Spawn.new("echo test")
|
||||
System.print(child.pid > 0) // expect: true
|
||||
System.print(child.timeout) // expect: 30
|
||||
child.timeout = 5
|
||||
System.print(child.timeout) // expect: 5
|
||||
System.print(child.maxread) // expect: 2000
|
||||
System.print(child.searchwindowsize) // expect: 0
|
||||
|
||||
child.expect(["test"])
|
||||
child.wait()
|
||||
System.print(child.exitstatus == 0) // expect: true
|
||||
child.close()
|
||||
Vendored
+23
@@ -0,0 +1,23 @@
|
||||
// retoor <retoor@molodetz.nl>
|
||||
// nontest
|
||||
|
||||
import "pexpect" for Spawn
|
||||
import "timer" for Timer
|
||||
|
||||
System.print("1. Creating child")
|
||||
var child = Spawn.new("echo hello")
|
||||
|
||||
System.print("2. Sleeping 200ms")
|
||||
Timer.sleep(200)
|
||||
|
||||
System.print("3. Buffer: [%(child.buffer)]")
|
||||
System.print("4. isalive: %(child.isalive)")
|
||||
|
||||
System.print("5. Calling readNonblocking")
|
||||
var data = child.readNonblocking(100, 1)
|
||||
System.print("6. Data: [%(data)]")
|
||||
|
||||
System.print("7. Buffer after read: [%(child.buffer)]")
|
||||
System.print("8. Closing")
|
||||
child.close()
|
||||
System.print("Done")
|
||||
Vendored
+9
@@ -0,0 +1,9 @@
|
||||
// retoor <retoor@molodetz.nl>
|
||||
// nontest
|
||||
|
||||
import "pexpect" for Spawn, Pexpect
|
||||
|
||||
System.print("Testing Pexpect.run")
|
||||
var output = Pexpect.run("echo test")
|
||||
System.print("Output: [%(output)]")
|
||||
System.print("Done")
|
||||
Vendored
+14
@@ -0,0 +1,14 @@
|
||||
// retoor <retoor@molodetz.nl>
|
||||
|
||||
import "pexpect" for Spawn, Pexpect
|
||||
|
||||
var child = Spawn.new("echo hello")
|
||||
var result = child.expect(["hello"])
|
||||
System.print(result) // expect: 0
|
||||
|
||||
child = Spawn.new("cat")
|
||||
child.sendline("test input")
|
||||
var idx = child.expect(["test input"])
|
||||
System.print(idx) // expect: 0
|
||||
child.sendeof()
|
||||
child.close()
|
||||
Vendored
+10
@@ -0,0 +1,10 @@
|
||||
// retoor <retoor@molodetz.nl>
|
||||
|
||||
import "pexpect" for Spawn, Pexpect
|
||||
|
||||
var child = Spawn.new("sleep 10")
|
||||
child.timeout = 0.5
|
||||
var result = child.expect(["never_match"])
|
||||
System.print(result) // expect: -2
|
||||
child.terminate(true)
|
||||
child.close()
|
||||
Vendored
+18
@@ -0,0 +1,18 @@
|
||||
// retoor <retoor@molodetz.nl>
|
||||
|
||||
import "yaml" for Yaml
|
||||
|
||||
var yaml = "
|
||||
# This is a comment
|
||||
name: test
|
||||
# Another comment
|
||||
value: 123
|
||||
"
|
||||
|
||||
var data = Yaml.parse(yaml)
|
||||
System.print(data["name"]) // expect: test
|
||||
System.print(data["value"]) // expect: 123
|
||||
|
||||
var inlineComment = "name: test # inline comment"
|
||||
var data2 = Yaml.parse(inlineComment)
|
||||
System.print(data2["name"]) // expect: test
|
||||
Vendored
+25
@@ -0,0 +1,25 @@
|
||||
// retoor <retoor@molodetz.nl>
|
||||
|
||||
import "yaml" for Yaml
|
||||
|
||||
var yaml = "
|
||||
sections:
|
||||
- title: Getting Started
|
||||
pages:
|
||||
- file: index
|
||||
title: Overview
|
||||
- file: installation
|
||||
title: Installation
|
||||
- title: API Reference
|
||||
pages:
|
||||
- file: json
|
||||
title: json
|
||||
"
|
||||
|
||||
var nav = Yaml.parse(yaml)
|
||||
System.print(nav["sections"][0]["title"]) // expect: Getting Started
|
||||
System.print(nav["sections"][0]["pages"][0]["file"]) // expect: index
|
||||
System.print(nav["sections"][0]["pages"][0]["title"]) // expect: Overview
|
||||
System.print(nav["sections"][0]["pages"][1]["file"]) // expect: installation
|
||||
System.print(nav["sections"][1]["title"]) // expect: API Reference
|
||||
System.print(nav["sections"][1]["pages"][0]["file"]) // expect: json
|
||||
Vendored
+12
@@ -0,0 +1,12 @@
|
||||
// retoor <retoor@molodetz.nl>
|
||||
|
||||
import "yaml" for Yaml
|
||||
|
||||
var empty = Yaml.parse("")
|
||||
System.print(empty) // expect: null
|
||||
|
||||
var nullInput = Yaml.parse(null)
|
||||
System.print(nullInput) // expect: null
|
||||
|
||||
var whitespace = Yaml.parse(" \n \n ")
|
||||
System.print(whitespace) // expect: null
|
||||
Vendored
+21
@@ -0,0 +1,21 @@
|
||||
// retoor <retoor@molodetz.nl>
|
||||
|
||||
import "yaml" for Yaml
|
||||
|
||||
var yaml = "items:\n - first\n - second\n - third"
|
||||
var data = Yaml.parse(yaml)
|
||||
System.print(data["items"][0]) // expect: first
|
||||
System.print(data["items"][1]) // expect: second
|
||||
System.print(data["items"][2]) // expect: third
|
||||
System.print(data["items"].count) // expect: 3
|
||||
|
||||
var simple = "- one\n- two\n- three"
|
||||
var list = Yaml.parse(simple)
|
||||
System.print(list[0]) // expect: one
|
||||
System.print(list[1]) // expect: two
|
||||
System.print(list.count) // expect: 3
|
||||
|
||||
var numbers = "- 1\n- 2\n- 3"
|
||||
var numList = Yaml.parse(numbers)
|
||||
System.print(numList[0]) // expect: 1
|
||||
System.print(numList[1]) // expect: 2
|
||||
Vendored
+17
@@ -0,0 +1,17 @@
|
||||
// retoor <retoor@molodetz.nl>
|
||||
|
||||
import "yaml" for Yaml
|
||||
|
||||
var yaml = "server:\n host: localhost\n port: 8080"
|
||||
var config = Yaml.parse(yaml)
|
||||
System.print(config["server"]["host"]) // expect: localhost
|
||||
System.print(config["server"]["port"]) // expect: 8080
|
||||
|
||||
var deep = "
|
||||
level1:
|
||||
level2:
|
||||
level3:
|
||||
value: deep
|
||||
"
|
||||
var deepConfig = Yaml.parse(deep)
|
||||
System.print(deepConfig["level1"]["level2"]["level3"]["value"]) // expect: deep
|
||||
Vendored
+27
@@ -0,0 +1,27 @@
|
||||
// retoor <retoor@molodetz.nl>
|
||||
|
||||
import "yaml" for Yaml
|
||||
|
||||
var simple = Yaml.parse("name: test")
|
||||
System.print(simple["name"]) // expect: test
|
||||
|
||||
var num = Yaml.parse("count: 42")
|
||||
System.print(num["count"]) // expect: 42
|
||||
|
||||
var float = Yaml.parse("value: 3.14")
|
||||
System.print(float["value"]) // expect: 3.14
|
||||
|
||||
var bool = Yaml.parse("active: true")
|
||||
System.print(bool["active"]) // expect: true
|
||||
|
||||
var boolFalse = Yaml.parse("active: false")
|
||||
System.print(boolFalse["active"]) // expect: false
|
||||
|
||||
var nullVal = Yaml.parse("value: null")
|
||||
System.print(nullVal["value"]) // expect: null
|
||||
|
||||
var quoted = Yaml.parse("name: \"hello world\"")
|
||||
System.print(quoted["name"]) // expect: hello world
|
||||
|
||||
var singleQuoted = Yaml.parse("name: 'hello world'")
|
||||
System.print(singleQuoted["name"]) // expect: hello world
|
||||
Vendored
+25
@@ -0,0 +1,25 @@
|
||||
// retoor <retoor@molodetz.nl>
|
||||
|
||||
import "yaml" for Yaml
|
||||
|
||||
var simple = {"name": "test", "value": 42}
|
||||
var str = Yaml.stringify(simple)
|
||||
System.print(str.contains("name: test")) // expect: true
|
||||
System.print(str.contains("value: 42")) // expect: true
|
||||
|
||||
var withList = {"items": ["one", "two", "three"]}
|
||||
var listStr = Yaml.stringify(withList)
|
||||
System.print(listStr.contains("items:")) // expect: true
|
||||
System.print(listStr.contains("- one")) // expect: true
|
||||
System.print(listStr.contains("- two")) // expect: true
|
||||
|
||||
var nested = {"server": {"host": "localhost", "port": 8080}}
|
||||
var nestedStr = Yaml.stringify(nested)
|
||||
System.print(nestedStr.contains("server:")) // expect: true
|
||||
System.print(nestedStr.contains("host: localhost")) // expect: true
|
||||
|
||||
System.print(Yaml.stringify(null)) // expect: null
|
||||
System.print(Yaml.stringify(true)) // expect: true
|
||||
System.print(Yaml.stringify(false)) // expect: false
|
||||
System.print(Yaml.stringify(42)) // expect: 42
|
||||
System.print(Yaml.stringify("hello")) // expect: hello
|
||||
Reference in New Issue
Block a user