functionalscript 0.0.410 → 0.0.411

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/Cargo.lock ADDED
@@ -0,0 +1,14 @@
1
+ # This file is automatically @generated by Cargo.
2
+ # It is not intended for manual editing.
3
+ version = 3
4
+
5
+ [[package]]
6
+ name = "com"
7
+ version = "0.1.0"
8
+
9
+ [[package]]
10
+ name = "rstest"
11
+ version = "0.1.0"
12
+ dependencies = [
13
+ "com",
14
+ ]
package/Cargo.toml ADDED
@@ -0,0 +1,5 @@
1
+ [workspace]
2
+ members = [
3
+ "com/rust/com",
4
+ "com/rust/com/rstest",
5
+ ]
@@ -0,0 +1,7 @@
1
+ # This file is automatically @generated by Cargo.
2
+ # It is not intended for manual editing.
3
+ version = 3
4
+
5
+ [[package]]
6
+ name = "com"
7
+ version = "0.1.0"
@@ -0,0 +1,8 @@
1
+ [package]
2
+ name = "com"
3
+ version = "0.1.0"
4
+ edition = "2021"
5
+
6
+ # See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
7
+
8
+ [dependencies]
@@ -0,0 +1,14 @@
1
+ # This file is automatically @generated by Cargo.
2
+ # It is not intended for manual editing.
3
+ version = 3
4
+
5
+ [[package]]
6
+ name = "com"
7
+ version = "0.1.0"
8
+
9
+ [[package]]
10
+ name = "rstest"
11
+ version = "0.1.0"
12
+ dependencies = [
13
+ "com",
14
+ ]
@@ -0,0 +1,9 @@
1
+ [package]
2
+ name = "rstest"
3
+ version = "0.1.0"
4
+ edition = "2021"
5
+
6
+ # See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
7
+
8
+ [dependencies]
9
+ com = { path = ".." }
@@ -0,0 +1,109 @@
1
+ #[cfg(test)]
2
+ mod test {
3
+ // interface definition:
4
+
5
+ mod library {
6
+ use com::{CObject, Class, Interface, Object, Ref, GUID};
7
+
8
+ #[allow(non_snake_case)]
9
+ #[repr(C)]
10
+ pub struct IMy {
11
+ pub A: unsafe extern "stdcall" fn(this: &Object<IMy>) -> Ref<IMy>,
12
+ pub B: unsafe extern "stdcall" fn(this: &Object<IMy>) -> u32,
13
+ }
14
+
15
+ impl Interface for IMy {
16
+ const GUID: GUID = 0x01234567_89AB_CDEF_0123_456789ABCDEF;
17
+ }
18
+
19
+ #[allow(non_snake_case)]
20
+ pub trait IMyEx {
21
+ fn A(&self) -> Ref<IMy>;
22
+ fn B(&self) -> u32;
23
+ }
24
+
25
+ #[allow(non_snake_case)]
26
+ impl IMyEx for Object<IMy> {
27
+ fn A(&self) -> Ref<IMy> {
28
+ unsafe { (self.interface().A)(self) }
29
+ }
30
+ fn B(&self) -> u32 {
31
+ unsafe { (self.interface().B)(self) }
32
+ }
33
+ }
34
+
35
+ pub trait IMyVmt: Class<Interface = IMy>
36
+ where
37
+ CObject<Self>: IMyEx,
38
+ {
39
+ const INTERFACE: IMy = IMy {
40
+ A: Self::A,
41
+ B: Self::B,
42
+ };
43
+ }
44
+
45
+ impl<T: Class<Interface = IMy>> IMyVmt for T where CObject<T>: IMyEx {}
46
+
47
+ #[allow(non_snake_case)]
48
+ trait IMyVmtFn: Class<Interface = IMy>
49
+ where
50
+ CObject<Self>: IMyEx,
51
+ {
52
+ extern "stdcall" fn A(this: &Object<IMy>) -> Ref<IMy> {
53
+ unsafe { Self::to_cobject(this) }.A()
54
+ }
55
+ extern "stdcall" fn B(this: &Object<IMy>) -> u32 {
56
+ unsafe { Self::to_cobject(this) }.B()
57
+ }
58
+ }
59
+
60
+ impl<T: Class<Interface = IMy>> IMyVmtFn for T where CObject<T>: IMyEx {}
61
+ }
62
+
63
+ // interface implementation
64
+ mod x {
65
+ use com::{CObject, Class, Ref, Vmt};
66
+
67
+ use super::library::{IMy, IMyEx, IMyVmt};
68
+
69
+ pub struct X(pub u32);
70
+
71
+ impl Class for X {
72
+ type Interface = IMy;
73
+ fn static_vmt() -> &'static Vmt<Self::Interface> {
74
+ static V: Vmt<IMy> = Vmt {
75
+ iunknown: X::IUNKNOWN,
76
+ interface: X::INTERFACE,
77
+ };
78
+ &V
79
+ }
80
+ }
81
+
82
+ #[allow(non_snake_case)]
83
+ impl IMyEx for CObject<X> {
84
+ fn A(&self) -> Ref<IMy> {
85
+ self.to_interface().into()
86
+ }
87
+ fn B(&self) -> u32 {
88
+ self.value.0
89
+ }
90
+ }
91
+ }
92
+
93
+ mod using {
94
+ use com::Class;
95
+
96
+ use crate::test::{library::IMyEx, x::X};
97
+
98
+ #[test]
99
+ fn test() {
100
+ let a = X(42).cobject_new();
101
+ let a1 = a.A();
102
+ assert_eq!(a, a1);
103
+ assert_eq!(a.B(), 42);
104
+ let b = X(43).cobject_new();
105
+ assert_ne!(a, b);
106
+ assert_eq!(b.B(), 43);
107
+ }
108
+ }
109
+ }
@@ -0,0 +1,14 @@
1
+ use crate::{iunknownvmt::IUnknownVmt, CObject, Interface, Object, Ref, Vmt};
2
+
3
+ pub trait Class: Sized {
4
+ type Interface: Interface;
5
+ fn static_vmt() -> &'static Vmt<Self::Interface>;
6
+ const IUNKNOWN: IUnknownVmt<Self::Interface> = CObject::<Self>::IUNKNOWN;
7
+ fn cobject_new(self) -> Ref<Self::Interface> {
8
+ CObject::new(self)
9
+ }
10
+ unsafe fn to_cobject(this: &Object<Self::Interface>) -> &CObject<Self> {
11
+ let p = this as *const Object<Self::Interface> as *const CObject<Self>;
12
+ &*p
13
+ }
14
+ }
@@ -0,0 +1,76 @@
1
+ use std::{
2
+ ptr::null,
3
+ sync::atomic::{AtomicU32, Ordering},
4
+ };
5
+
6
+ use crate::{
7
+ hresult::HRESULT, iunknown::IUnknown, iunknownvmt::IUnknownVmt, Class, Interface, Object, Ref,
8
+ Vmt,
9
+ };
10
+
11
+ #[repr(C)]
12
+ pub struct CObject<T: Class> {
13
+ vmt: &'static Vmt<T::Interface>,
14
+ counter: AtomicU32,
15
+ pub value: T,
16
+ }
17
+
18
+ impl<T: Class> CObject<T> {
19
+ pub fn new(value: T) -> Ref<T::Interface> {
20
+ let c = CObject {
21
+ vmt: T::static_vmt(),
22
+ counter: Default::default(),
23
+ value,
24
+ };
25
+ let p = Box::into_raw(Box::new(c));
26
+ unsafe { &*p }.to_interface().into()
27
+ }
28
+
29
+ pub fn to_interface(&self) -> &Object<T::Interface> {
30
+ let p = self as *const Self as *const Object<T::Interface>;
31
+ unsafe { &*p }
32
+ }
33
+
34
+ pub const IUNKNOWN: IUnknownVmt<T::Interface> = IUnknownVmt {
35
+ QueryInterface: Self::QueryInterface,
36
+ AddRef: Self::AddRef,
37
+ Release: Self::Release,
38
+ };
39
+
40
+ #[allow(non_snake_case)]
41
+ extern "stdcall" fn QueryInterface(
42
+ this: &Object<T::Interface>,
43
+ riid: &u128,
44
+ ppv_object: &mut *const Object<IUnknown>,
45
+ ) -> HRESULT {
46
+ let (p, r) = if *riid == IUnknown::GUID || *riid == T::Interface::GUID {
47
+ Self::AddRef(this);
48
+ (this.to_iunknown() as *const Object<IUnknown>, HRESULT::S_OK)
49
+ } else {
50
+ (null(), HRESULT::E_NOINTERFACE)
51
+ };
52
+ *ppv_object = p;
53
+ r
54
+ }
55
+
56
+ #[allow(non_snake_case)]
57
+ extern "stdcall" fn AddRef(this: &Object<T::Interface>) -> u32 {
58
+ unsafe { T::to_cobject(this) }
59
+ .counter
60
+ .fetch_add(1, Ordering::Relaxed)
61
+ + 1
62
+ }
63
+
64
+ #[allow(non_snake_case)]
65
+ extern "stdcall" fn Release(this: &Object<T::Interface>) -> u32 {
66
+ let t = unsafe { T::to_cobject(this) };
67
+ match t.counter.fetch_sub(1, Ordering::Relaxed) {
68
+ 1 => {
69
+ let m = t as *const CObject<T> as *mut CObject<T>;
70
+ unsafe { Box::from_raw(m) };
71
+ 0
72
+ }
73
+ x => x - 1,
74
+ }
75
+ }
76
+ }
@@ -0,0 +1 @@
1
+ pub type GUID = u128;
@@ -0,0 +1,7 @@
1
+ #[allow(non_camel_case_types)]
2
+ #[repr(u32)]
3
+ #[derive(Debug)]
4
+ pub enum HRESULT {
5
+ S_OK = 0,
6
+ E_NOINTERFACE = 0x80004002,
7
+ }
@@ -0,0 +1,5 @@
1
+ use crate::guid::GUID;
2
+
3
+ pub trait Interface: 'static {
4
+ const GUID: GUID;
5
+ }
@@ -0,0 +1,7 @@
1
+ use crate::{guid::GUID, interface::Interface};
2
+
3
+ pub struct IUnknown();
4
+
5
+ impl Interface for IUnknown {
6
+ const GUID: GUID = 0x00000000_0000_0000_C000_000000000046;
7
+ }
@@ -0,0 +1,13 @@
1
+ use crate::{hresult::HRESULT, iunknown::IUnknown, Object, GUID};
2
+
3
+ #[allow(non_snake_case)]
4
+ #[repr(C)]
5
+ pub struct IUnknownVmt<I: 'static> {
6
+ pub QueryInterface: unsafe extern "stdcall" fn(
7
+ this: &Object<I>,
8
+ riid: &GUID,
9
+ ppv_object: &mut *const Object<IUnknown>,
10
+ ) -> HRESULT,
11
+ pub AddRef: unsafe extern "stdcall" fn(this: &Object<I>) -> u32,
12
+ pub Release: unsafe extern "stdcall" fn(this: &Object<I>) -> u32,
13
+ }
@@ -0,0 +1,15 @@
1
+ mod class;
2
+ mod cobject;
3
+ mod guid;
4
+ mod hresult;
5
+ mod interface;
6
+ mod iunknown;
7
+ mod iunknownvmt;
8
+ mod object;
9
+ mod r#ref;
10
+ mod vmt;
11
+
12
+ pub use crate::{
13
+ class::Class, cobject::CObject, guid::GUID, interface::Interface, object::Object, r#ref::Ref,
14
+ vmt::Vmt,
15
+ };
@@ -0,0 +1,34 @@
1
+ use crate::{
2
+ hresult::HRESULT, interface::Interface, iunknown::IUnknown, iunknownvmt::IUnknownVmt,
3
+ r#ref::Ref, vmt::Vmt,
4
+ };
5
+ use std::ptr::null;
6
+
7
+ #[repr(C)]
8
+ pub struct Object<I: 'static>(&'static Vmt<I>);
9
+
10
+ impl<I> Object<I> {
11
+ pub unsafe fn iunknown(&self) -> &'static IUnknownVmt<I> {
12
+ &self.0.iunknown
13
+ }
14
+ pub unsafe fn interface(&self) -> &'static I {
15
+ &self.0.interface
16
+ }
17
+ pub fn to_iunknown(&self) -> &Object<IUnknown> {
18
+ let p = self as *const Object<I> as *const Object<IUnknown>;
19
+ unsafe { &*p }
20
+ }
21
+ pub fn query_interface<J: Interface>(&self) -> Result<Ref<J>, HRESULT> {
22
+ let mut p = null();
23
+ match unsafe { (self.0.iunknown.QueryInterface)(self, &J::GUID, &mut p) } {
24
+ HRESULT::S_OK => {
25
+ let r = p as *const Object<J>;
26
+ Ok(unsafe { Ref::from_raw(r) })
27
+ }
28
+ e => Err(e),
29
+ }
30
+ }
31
+ pub fn query_iunknown(&self) -> Ref<IUnknown> {
32
+ self.query_interface().unwrap()
33
+ }
34
+ }
@@ -0,0 +1,53 @@
1
+ use std::{cmp::Eq, fmt::Debug, ops::Deref};
2
+
3
+ use crate::object::Object;
4
+
5
+ #[repr(transparent)]
6
+ pub struct Ref<I: 'static>(*const Object<I>);
7
+
8
+ impl<I: 'static> Ref<I> {
9
+ pub unsafe fn from_raw(p: *const Object<I>) -> Ref<I> {
10
+ Ref(p)
11
+ }
12
+ }
13
+
14
+ impl<I> Deref for Ref<I> {
15
+ type Target = Object<I>;
16
+ fn deref(&self) -> &Self::Target {
17
+ let p = self.0;
18
+ unsafe { &*p }
19
+ }
20
+ }
21
+
22
+ impl<I> Drop for Ref<I> {
23
+ fn drop(&mut self) {
24
+ unsafe { (self.iunknown().Release)(self) };
25
+ }
26
+ }
27
+
28
+ impl<I> Clone for Ref<I> {
29
+ fn clone(&self) -> Self {
30
+ self.deref().into()
31
+ }
32
+ }
33
+
34
+ impl<I> From<&Object<I>> for Ref<I> {
35
+ fn from(this: &Object<I>) -> Self {
36
+ unsafe { (this.iunknown().AddRef)(this) };
37
+ Self(this)
38
+ }
39
+ }
40
+
41
+ impl<I> Debug for Ref<I> {
42
+ fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
43
+ f.debug_tuple("Ref").field(&self.0).finish()
44
+ }
45
+ }
46
+
47
+ impl<I> PartialEq for Ref<I> {
48
+ fn eq(&self, other: &Self) -> bool {
49
+ self.0 == other.0
50
+ }
51
+ }
52
+
53
+ impl<I> Eq for Ref<I> {}
@@ -0,0 +1,7 @@
1
+ use crate::iunknownvmt::IUnknownVmt;
2
+
3
+ #[repr(C)]
4
+ pub struct Vmt<I: 'static> {
5
+ pub iunknown: IUnknownVmt<I>,
6
+ pub interface: I,
7
+ }
@@ -0,0 +1,10 @@
1
+ const types = require('../types/module.f.cjs')
2
+ const text = require('../../text/module.f.cjs')
3
+
4
+ /** @type {(name: string) => (library: types.Library) => text.Block} */
5
+ const rust = name => library => []
6
+
7
+ module.exports = {
8
+ /** @readonly */
9
+ rust,
10
+ }
@@ -0,0 +1,11 @@
1
+ const { rust } = require('./module.f.cjs')
2
+ const { flat } = require('../../text/module.f.cjs')
3
+ const { join } = require('../../types/string/module.f.cjs')
4
+ const library = require('../types/test.f.cjs')
5
+
6
+ {
7
+ const r = join('\n')(flat(' ')(rust('My')(library)))
8
+ if (r !== '') { throw r }
9
+ }
10
+
11
+ module.exports = {}
package/doc/vm.md CHANGED
@@ -68,27 +68,6 @@ Least used letters in English: Q, J, Z and X.
68
68
 
69
69
  Starts with `0xFFF`
70
70
 
71
- - `50`:
72
- - `48`: stringUInt48 (0..281_474_976_710_655)
73
- - `48`: 8 x 6 string
74
- - `48`: `42` 7 x 6 string
75
- - `48`: 6 x 8 string
76
- - `50`:
77
- - `48`: `45` 5 x 9 string
78
- - `48`: 4 x 12 string
79
- - `48`: 3 x 16 string
80
- - `48`: `32`: 2 x 16 string
81
- - `50`:
82
- - `48`: `16`: 1 x 16 string
83
- - `48`: `0`: ""
84
- - `48`: false
85
- - `48`: true
86
- - `50`:
87
- - `48`: ptr
88
- - `48`: bigInt48 (140_737_488_355_328..140_737_488_355_327)
89
- - `48`: undefined
90
- - `48`: `-inf`
91
-
92
71
  | | | |type |
93
72
  |------|--|-------------|-----------|
94
73
  |`1111`|48|stringUInt48 |`string` |
package/html/module.f.cjs CHANGED
@@ -3,9 +3,7 @@ const { map, flatMap, flat, concat: listConcat } = list
3
3
  const { concat: stringConcat } = require('../types/string/module.f.cjs')
4
4
  const object = require('../types/object/module.f.cjs')
5
5
  const { compose } = require('../types/function/module.f.cjs')
6
- const encoding = require('../text/utf16/module.f.cjs');
7
- const { stringToList } = encoding
8
-
6
+ const { stringToList } = require('../text/utf16/module.f.cjs')
9
7
  const { fromCharCode } = String
10
8
  const { entries } = Object
11
9
 
package/json/module.f.cjs CHANGED
@@ -1,10 +1,10 @@
1
1
  const list = require('../types/list/module.f.cjs')
2
- const { next, flat, reduce: fold, map } = list
2
+ const { next, flat, reduce, map, empty } = list
3
3
  const { concat } = require('../types/string/module.f.cjs')
4
4
  const object = require('../types/object/module.f.cjs')
5
5
  const { at } = object
6
6
  const operator = require('../types/function/operator/module.f.cjs')
7
- const { compose } = require('../types/function/module.f.cjs')
7
+ const { compose, fn } = require('../types/function/module.f.cjs')
8
8
  const { entries } = Object
9
9
 
10
10
  /**
@@ -54,7 +54,7 @@ const comma = [',']
54
54
  const joinOp = b => prior => flat([prior, comma, b])
55
55
 
56
56
  /** @type {(input: list.List<list.List<string>>) => list.List<string>} */
57
- const join = fold(joinOp)([])
57
+ const join = reduce(joinOp)(empty)
58
58
 
59
59
  /** @type {(open: string) => (close: string) => (input: list.List<list.List<string>>) => list.List<string>} */
60
60
  const wrap = open => close => {
@@ -83,7 +83,11 @@ const serialize = sort => {
83
83
  ])
84
84
  const mapPropertySerialize = map(propertySerialize)
85
85
  /** @type {(object: Object) => list.List<string>} */
86
- const objectSerialize = input => objectWrap(mapPropertySerialize(sort(entries(input))))
86
+ const objectSerialize = fn(entries)
87
+ .then(sort)
88
+ .then(mapPropertySerialize)
89
+ .then(objectWrap)
90
+ .result
87
91
  /** @type {(value: Unknown) => list.List<string>} */
88
92
  const f = value => {
89
93
  switch (typeof value) {
@@ -97,9 +101,7 @@ const serialize = sort => {
97
101
  }
98
102
  }
99
103
  }
100
- const mapF = map(f)
101
- /** @type {(input: Array) => list.List<string>} */
102
- const arraySerialize = compose(mapF)(arrayWrap)
104
+ const arraySerialize = compose(map(f))(arrayWrap)
103
105
  return f
104
106
  }
105
107
 
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "functionalscript",
3
- "version": "0.0.410",
3
+ "version": "0.0.411",
4
4
  "description": "FunctionalScript is a functional subset of JavaScript",
5
5
  "main": "module.f.cjs",
6
6
  "scripts": {
package/test.f.cjs CHANGED
@@ -27,6 +27,7 @@ require('./text/utf16/test.f.cjs')
27
27
  require('./com/cs/test.f.cjs')
28
28
  require('./com/cpp/test.f.cjs')
29
29
  require('./nodejs/version/test.f.cjs')
30
+ require('./com/rust/test.f.cjs')
30
31
 
31
32
  /** @type {() => never} */
32
33
  const assert = () => { throw 'assert' }