-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathffi.ov
More file actions
64 lines (50 loc) · 2.36 KB
/
Copy pathffi.ov
File metadata and controls
64 lines (50 loc) · 2.36 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
module ffi_example
// Three platforms, one declaration syntax.
// The Overt signature is the normalized one the agent sees; the compiler
// handles all boundary conversion (exceptions → Result, nullable → Option,
// primitive marshaling).
// Import a .NET static method. C# exceptions become Err at the boundary.
extern "csharp" fn file_exists(path: String) !{io} -> Bool
binds "System.IO.File.Exists"
// Opaque types + the three extern shapes. The `extern type` line makes
// `StringBuilder` visible as an Overt nominal type; `ctor fn` binds a
// constructor; `instance fn` binds a method whose first parameter is
// the receiver (`self`). Binds targets are always dotted paths — the
// kind keyword selects the call shape, not the target string.
extern "csharp" type StringBuilder binds "System.Text.StringBuilder"
extern "csharp" ctor fn sb_new() -> StringBuilder
binds "System.Text.StringBuilder"
extern "csharp" instance fn sb_append(self: StringBuilder, s: String) -> StringBuilder
binds "System.Text.StringBuilder.Append"
extern "csharp" instance fn sb_to_string(self: StringBuilder) -> String
binds "System.Text.StringBuilder.ToString"
// Import a Go function. Go's (value, ok) pattern becomes Option.
extern "go" fn env_value(key: String) !{io} -> Option<String>
binds "os.LookupEnv"
// Import a C function. Requires `unsafe` and `from`.
// CString and Ptr<T> are distinct types from Overt String and List — conversions
// across the C boundary are always explicit.
unsafe extern "c" fn c_strlen(s: CString) -> Int
binds "strlen"
from "libc"
// Safe Overt wrapper around the unsafe C binding.
// From here on, no other code touches c_strlen directly.
fn strlen(s: String) -> Int {
let cs: CString = CString.from(s)
unsafe { c_strlen(cs) }
}
fn main() !{io} -> Result<(), IoError> {
let exists: Bool = file_exists("/tmp/hello.txt")
println("file exists: $exists")?
match env_value("HOME") {
Some(home) => println("HOME=$home"),
None => println("HOME is not set"),
}?
println("length of \"hello\" = ${strlen("hello")}")?
// Opaque-type flow: construct, chain instance methods, extract.
let b1: StringBuilder = sb_new()
let b2: StringBuilder = sb_append(self = b1, s = "hello ")
let b3: StringBuilder = sb_append(self = b2, s = "world")
println("built: ${sb_to_string(b3)}")?
Ok(())
}