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
+71
@@ -0,0 +1,71 @@
|
||||
// retoor <retoor@molodetz.nl>
|
||||
|
||||
import "pexpect" for Spawn, Pexpect
|
||||
|
||||
System.print("=== Pexpect Module Demo ===\n")
|
||||
|
||||
System.print("--- Basic Spawn and Expect ---")
|
||||
var child = Spawn.new("echo 'Hello from pexpect!'")
|
||||
var idx = child.expect(["Hello"])
|
||||
System.print("Matched pattern index: %(idx)")
|
||||
System.print("After match: %(child.after)")
|
||||
child.close()
|
||||
|
||||
System.print("\n--- Interactive Process ---")
|
||||
child = Spawn.new("cat")
|
||||
child.sendline("First line")
|
||||
child.expect(["First line"])
|
||||
System.print("Echo received: %(child.after)")
|
||||
child.sendline("Second line")
|
||||
child.expect(["Second line"])
|
||||
System.print("Echo received: %(child.after)")
|
||||
child.sendeof()
|
||||
child.close()
|
||||
|
||||
System.print("\n--- Multiple Patterns ---")
|
||||
child = Spawn.new("printf 'username: '")
|
||||
idx = child.expect(["password:", "username:", "login:"])
|
||||
System.print("Matched: %(idx == 1 ? "username" : "other")")
|
||||
child.close()
|
||||
|
||||
System.print("\n--- Exact String Matching ---")
|
||||
child = Spawn.new("echo 'The answer is 42'")
|
||||
idx = child.expectExact(["42"])
|
||||
System.print("Found exact match: %(child.after)")
|
||||
System.print("Text before: %(child.before)")
|
||||
child.close()
|
||||
|
||||
System.print("\n--- Timeout Handling ---")
|
||||
child = Spawn.new("sleep 10")
|
||||
child.timeout = 0.5
|
||||
idx = child.expect(["never_match"])
|
||||
if (idx == Pexpect.TIMEOUT) {
|
||||
System.print("Got timeout as expected")
|
||||
}
|
||||
child.terminate(true)
|
||||
child.close()
|
||||
|
||||
System.print("\n--- Process Properties ---")
|
||||
child = Spawn.new("echo test")
|
||||
System.print("PID: %(child.pid)")
|
||||
System.print("Is alive: %(child.isalive)")
|
||||
child.expect(["test"])
|
||||
child.wait()
|
||||
System.print("Exit status: %(child.exitstatus)")
|
||||
child.close()
|
||||
|
||||
System.print("\n--- Read Non-blocking ---")
|
||||
child = Spawn.new("printf 'quick output'")
|
||||
var data = child.readNonblocking(100, 1)
|
||||
System.print("Read: %(data.trim())")
|
||||
child.close()
|
||||
|
||||
System.print("\n--- Constants ---")
|
||||
System.print("EOF constant: %(Pexpect.EOF)")
|
||||
System.print("TIMEOUT constant: %(Pexpect.TIMEOUT)")
|
||||
|
||||
System.print("\n--- Pexpect.run() ---")
|
||||
var output = Pexpect.run("echo 'Simple run'")
|
||||
System.print("Output: %(output.trim())")
|
||||
|
||||
System.print("\n=== Demo Complete ===")
|
||||
Vendored
+105
@@ -0,0 +1,105 @@
|
||||
// retoor <retoor@molodetz.nl>
|
||||
|
||||
import "yaml" for Yaml
|
||||
|
||||
System.print("=== YAML Module Demo ===\n")
|
||||
|
||||
System.print("--- Basic Parsing ---")
|
||||
var simple = Yaml.parse("name: Wren-CLI\nversion: 0.4.0")
|
||||
System.print("Name: %(simple["name"])")
|
||||
System.print("Version: %(simple["version"])")
|
||||
|
||||
System.print("\n--- Nested Structures ---")
|
||||
var nested = "
|
||||
database:
|
||||
host: localhost
|
||||
port: 5432
|
||||
credentials:
|
||||
user: admin
|
||||
password: secret
|
||||
"
|
||||
var config = Yaml.parse(nested)
|
||||
System.print("Host: %(config["database"]["host"])")
|
||||
System.print("Port: %(config["database"]["port"])")
|
||||
System.print("User: %(config["database"]["credentials"]["user"])")
|
||||
|
||||
System.print("\n--- Lists ---")
|
||||
var listYaml = "
|
||||
languages:
|
||||
- Wren
|
||||
- C
|
||||
- Python
|
||||
"
|
||||
var langs = Yaml.parse(listYaml)
|
||||
System.print("Languages:")
|
||||
for (lang in langs["languages"]) {
|
||||
System.print(" - %(lang)")
|
||||
}
|
||||
|
||||
System.print("\n--- Complex Structure (Navigation) ---")
|
||||
var navYaml = "
|
||||
sections:
|
||||
- title: Getting Started
|
||||
pages:
|
||||
- file: index
|
||||
title: Overview
|
||||
- file: installation
|
||||
title: Installation
|
||||
- title: API Reference
|
||||
pages:
|
||||
- file: yaml
|
||||
title: yaml
|
||||
"
|
||||
var nav = Yaml.parse(navYaml)
|
||||
for (section in nav["sections"]) {
|
||||
System.print("Section: %(section["title"])")
|
||||
for (page in section["pages"]) {
|
||||
System.print(" - %(page["title"]) (%(page["file"]))")
|
||||
}
|
||||
}
|
||||
|
||||
System.print("\n--- Data Types ---")
|
||||
var types = "
|
||||
string: hello world
|
||||
number: 42
|
||||
float: 3.14159
|
||||
bool_true: true
|
||||
bool_false: false
|
||||
null_value: null
|
||||
quoted: \"with spaces\"
|
||||
"
|
||||
var data = Yaml.parse(types)
|
||||
System.print("String: %(data["string"]) (%(data["string"].type))")
|
||||
System.print("Number: %(data["number"]) (%(data["number"].type))")
|
||||
System.print("Float: %(data["float"]) (%(data["float"].type))")
|
||||
System.print("Bool true: %(data["bool_true"]) (%(data["bool_true"].type))")
|
||||
System.print("Bool false: %(data["bool_false"]) (%(data["bool_false"].type))")
|
||||
System.print("Null: %(data["null_value"])")
|
||||
System.print("Quoted: %(data["quoted"])")
|
||||
|
||||
System.print("\n--- Stringify ---")
|
||||
var obj = {
|
||||
"name": "Example",
|
||||
"count": 42,
|
||||
"active": true,
|
||||
"items": ["one", "two", "three"],
|
||||
"nested": {
|
||||
"key": "value"
|
||||
}
|
||||
}
|
||||
System.print("Serialized:")
|
||||
System.print(Yaml.stringify(obj))
|
||||
|
||||
System.print("\n--- Round-trip ---")
|
||||
var original = "
|
||||
title: Test
|
||||
items:
|
||||
- first
|
||||
- second
|
||||
"
|
||||
var parsed = Yaml.parse(original)
|
||||
var reserialized = Yaml.stringify(parsed)
|
||||
var reparsed = Yaml.parse(reserialized)
|
||||
System.print("Original title: %(parsed["title"])")
|
||||
System.print("Reparsed title: %(reparsed["title"])")
|
||||
System.print("Items match: %(parsed["items"][0] == reparsed["items"][0])")
|
||||
Reference in New Issue
Block a user