Updated everything and moved to hard tab indentation

This commit is contained in:
2025-01-08 19:20:34 +01:00
parent 7cdfe7e3c4
commit 52c8d1c95a
100 changed files with 5949 additions and 5998 deletions

View File

@@ -6,6 +6,6 @@ edition = "2021"
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
[dependencies]
ordered-float = "4.2.0"
ordered-float = "4.6.0"
orchid-api-traits = { version = "0.1.0", path = "../orchid-api-traits" }
orchid-api-derive = { version = "0.1.0", path = "../orchid-api-derive" }

View File

@@ -3,7 +3,9 @@ use std::num::NonZeroU64;
use orchid_api_derive::{Coding, Hierarchy};
use orchid_api_traits::Request;
use crate::{ExprTicket, Expression, ExtHostReq, HostExtNotif, HostExtReq, OrcResult, SysId, TStrv};
use crate::{
ExprTicket, Expression, ExtHostReq, HostExtNotif, HostExtReq, OrcResult, SysId, TStrv,
};
pub type AtomData = Vec<u8>;
@@ -15,34 +17,34 @@ pub struct AtomId(pub NonZeroU64);
/// This has the same semantics as [Atom] except in that the owner is implied.
#[derive(Clone, Debug, Hash, PartialEq, Eq, Coding)]
pub struct LocalAtom {
pub drop: Option<AtomId>,
pub data: AtomData,
pub drop: Option<AtomId>,
pub data: AtomData,
}
impl LocalAtom {
pub fn associate(self, owner: SysId) -> Atom { Atom { owner, drop: self.drop, data: self.data } }
pub fn associate(self, owner: SysId) -> Atom { Atom { owner, drop: self.drop, data: self.data } }
}
/// An atom representation that can be serialized and sent around. Atoms
/// represent the smallest increment of work.
#[derive(Clone, Debug, Hash, PartialEq, Eq, Coding)]
pub struct Atom {
/// Instance ID of the system that created the atom
pub owner: SysId,
/// Indicates how the owner should be notified when this atom is dropped.
/// Construction is always explicit and atoms are never cloned.
///
/// Atoms with `drop == None` are also known as trivial, they can be
/// duplicated and stored with no regard to expression lifetimes. NOTICE
/// that this only applies to the atom. If it's referenced with an
/// [ExprTicket], the ticket itself can still expire.
///
/// Notice also that the atoms still expire when the system is dropped, and
/// are not portable across instances of the same system, so this doesn't
/// imply that the atom is serializable.
pub drop: Option<AtomId>,
/// Data stored in the atom. This could be a key into a map, or the raw data
/// of the atom if it isn't too big.
pub data: AtomData,
/// Instance ID of the system that created the atom
pub owner: SysId,
/// Indicates how the owner should be notified when this atom is dropped.
/// Construction is always explicit and atoms are never cloned.
///
/// Atoms with `drop == None` are also known as trivial, they can be
/// duplicated and stored with no regard to expression lifetimes. NOTICE
/// that this only applies to the atom. If it's referenced with an
/// [ExprTicket], the ticket itself can still expire.
///
/// Notice also that the atoms still expire when the system is dropped, and
/// are not portable across instances of the same system, so this doesn't
/// imply that the atom is serializable.
pub drop: Option<AtomId>,
/// Data stored in the atom. This could be a key into a map, or the raw data
/// of the atom if it isn't too big.
pub data: AtomData,
}
/// Attempt to apply an atom as a function to an expression
@@ -50,7 +52,7 @@ pub struct Atom {
#[extends(AtomReq, HostExtReq)]
pub struct CallRef(pub Atom, pub ExprTicket);
impl Request for CallRef {
type Response = Expression;
type Response = Expression;
}
/// Attempt to apply an atom as a function, consuming the atom and enabling the
@@ -60,21 +62,21 @@ impl Request for CallRef {
#[extends(AtomReq, HostExtReq)]
pub struct FinalCall(pub Atom, pub ExprTicket);
impl Request for FinalCall {
type Response = Expression;
type Response = Expression;
}
#[derive(Clone, Debug, Hash, PartialEq, Eq, Coding, Hierarchy)]
#[extends(AtomReq, HostExtReq)]
pub struct SerializeAtom(pub Atom);
impl Request for SerializeAtom {
type Response = Option<(Vec<u8>, Vec<ExprTicket>)>;
type Response = Option<(Vec<u8>, Vec<ExprTicket>)>;
}
#[derive(Clone, Debug, Hash, PartialEq, Eq, Coding, Hierarchy)]
#[extends(HostExtReq)]
pub struct DeserAtom(pub SysId, pub Vec<u8>, pub Vec<ExprTicket>);
impl Request for DeserAtom {
type Response = Atom;
type Response = Atom;
}
/// A request blindly routed to the system that provides an atom.
@@ -82,26 +84,26 @@ impl Request for DeserAtom {
#[extends(AtomReq, HostExtReq)]
pub struct Fwded(pub Atom, pub TStrv, pub Vec<u8>);
impl Request for Fwded {
type Response = Option<Vec<u8>>;
type Response = Option<Vec<u8>>;
}
#[derive(Clone, Debug, Hash, PartialEq, Eq, Coding, Hierarchy)]
#[extends(ExtHostReq)]
pub struct Fwd(pub Atom, pub TStrv, pub Vec<u8>);
impl Request for Fwd {
type Response = Option<Vec<u8>>;
type Response = Option<Vec<u8>>;
}
#[derive(Clone, Debug, Coding)]
pub enum NextStep {
Continue(Expression),
Halt,
Continue(Expression),
Halt,
}
#[derive(Clone, Debug, Hash, PartialEq, Eq, Coding, Hierarchy)]
#[extends(AtomReq, HostExtReq)]
pub struct Command(pub Atom);
impl Request for Command {
type Response = OrcResult<NextStep>;
type Response = OrcResult<NextStep>;
}
/// Notification that an atom is being dropped because its associated expression
@@ -115,7 +117,7 @@ pub struct AtomDrop(pub SysId, pub AtomId);
#[extends(AtomReq, HostExtReq)]
pub struct AtomPrint(pub Atom);
impl Request for AtomPrint {
type Response = String;
type Response = String;
}
/// Requests that apply to an existing atom instance
@@ -123,24 +125,24 @@ impl Request for AtomPrint {
#[extends(HostExtReq)]
#[extendable]
pub enum AtomReq {
CallRef(CallRef),
FinalCall(FinalCall),
Fwded(Fwded),
Command(Command),
AtomPrint(AtomPrint),
SerializeAtom(SerializeAtom),
CallRef(CallRef),
FinalCall(FinalCall),
Fwded(Fwded),
Command(Command),
AtomPrint(AtomPrint),
SerializeAtom(SerializeAtom),
}
impl AtomReq {
/// Obtain the first [Atom] argument of the request. All requests in this
/// subclass have at least one atom argument.
pub fn get_atom(&self) -> &Atom {
match self {
Self::CallRef(CallRef(a, ..))
| Self::Command(Command(a))
| Self::FinalCall(FinalCall(a, ..))
| Self::Fwded(Fwded(a, ..))
| Self::AtomPrint(AtomPrint(a))
| Self::SerializeAtom(SerializeAtom(a)) => a,
}
}
/// Obtain the first [Atom] argument of the request. All requests in this
/// subclass have at least one atom argument.
pub fn get_atom(&self) -> &Atom {
match self {
Self::CallRef(CallRef(a, ..))
| Self::Command(Command(a))
| Self::FinalCall(FinalCall(a, ..))
| Self::Fwded(Fwded(a, ..))
| Self::AtomPrint(AtomPrint(a))
| Self::SerializeAtom(SerializeAtom(a)) => a,
}
}
}

View File

@@ -10,11 +10,11 @@ pub struct ErrId(pub NonZeroU16);
#[derive(Clone, Debug, Coding)]
pub struct ErrLocation {
/// Description of the relation of this location to the error. If not used,
/// set to empty string
pub message: Arc<String>,
/// Location in code where the error emerged. This is usually [Location::Gen].
pub location: Location,
/// Description of the relation of this location to the error. If not used,
/// set to empty string
pub message: Arc<String>,
/// Location in code where the error emerged. This is usually [Location::Gen].
pub location: Location,
}
/// Programming errors raised by extensions. At runtime these produce the
@@ -24,14 +24,14 @@ pub struct ErrLocation {
/// and a bottom if the file name isn't a string.
#[derive(Clone, Debug, Coding)]
pub struct OrcError {
/// General description of the kind of error.
pub description: TStr,
/// Specific information about the exact error, preferably containing concrete
/// values.
pub message: Arc<String>,
/// Specific code fragments that have contributed to the emergence of the
/// error.
pub locations: Vec<ErrLocation>,
/// General description of the kind of error.
pub description: TStr,
/// Specific information about the exact error, preferably containing concrete
/// values.
pub message: Arc<String>,
/// Specific code fragments that have contributed to the emergence of the
/// error.
pub locations: Vec<ErrLocation>,
}
/// If this is an [`Err`] then the [`Vec`] must not be empty.

View File

@@ -43,9 +43,9 @@ pub struct Release(pub SysId, pub ExprTicket);
#[derive(Clone, Copy, Debug, Hash, PartialEq, Eq, Coding, Hierarchy)]
#[extends(ExprNotif, ExtHostNotif)]
pub struct Move {
pub dec: SysId,
pub inc: SysId,
pub expr: ExprTicket,
pub dec: SysId,
pub inc: SysId,
pub expr: ExprTicket,
}
/// A description of a new expression. It is used as the return value of
@@ -53,48 +53,48 @@ pub struct Move {
/// [crate::tree::Tree].
#[derive(Clone, Debug, Coding)]
pub enum ExpressionKind {
/// Apply the lhs as a function to the rhs
Call(Box<Expression>, Box<Expression>),
/// Lambda function. The number operates as an argument name
Lambda(u64, Box<Expression>),
/// Binds the argument passed to the lambda with the same ID in the same
/// template
Arg(u64),
/// Insert the specified host-expression in the template here. When the clause
/// is used in the const tree, this variant is forbidden.
Slot(ExprTicket),
/// The lhs must be fully processed before the rhs can be processed.
/// Equivalent to Haskell's function of the same name
Seq(Box<Expression>, Box<Expression>),
/// Insert a new atom in the tree. When the clause is used in the const tree,
/// the atom must be trivial. This is always a newly constructed atom, if you
/// want to reference an existing atom, use the corresponding [ExprTicket].
/// Because the atom is newly constructed, it also must belong to this system.
NewAtom(Atom),
/// A reference to a constant
Const(TStrv),
/// A static runtime error.
Bottom(Vec<OrcError>),
/// Apply the lhs as a function to the rhs
Call(Box<Expression>, Box<Expression>),
/// Lambda function. The number operates as an argument name
Lambda(u64, Box<Expression>),
/// Binds the argument passed to the lambda with the same ID in the same
/// template
Arg(u64),
/// Insert the specified host-expression in the template here. When the clause
/// is used in the const tree, this variant is forbidden.
Slot(ExprTicket),
/// The lhs must be fully processed before the rhs can be processed.
/// Equivalent to Haskell's function of the same name
Seq(Box<Expression>, Box<Expression>),
/// Insert a new atom in the tree. When the clause is used in the const tree,
/// the atom must be trivial. This is always a newly constructed atom, if you
/// want to reference an existing atom, use the corresponding [ExprTicket].
/// Because the atom is newly constructed, it also must belong to this system.
NewAtom(Atom),
/// A reference to a constant
Const(TStrv),
/// A static runtime error.
Bottom(Vec<OrcError>),
}
#[derive(Clone, Debug, Coding)]
pub struct Expression {
pub kind: ExpressionKind,
pub location: Location,
pub kind: ExpressionKind,
pub location: Location,
}
#[derive(Clone, Debug, Coding)]
pub enum InspectedKind {
Atom(Atom),
Bottom(Vec<OrcError>),
Opaque,
Atom(Atom),
Bottom(Vec<OrcError>),
Opaque,
}
#[derive(Clone, Debug, Coding)]
pub struct Inspected {
pub kind: InspectedKind,
pub location: Location,
pub refcount: u32,
pub kind: InspectedKind,
pub location: Location,
pub refcount: u32,
}
/// Obtain information about an expression. Used to act upon arguments by
@@ -103,24 +103,24 @@ pub struct Inspected {
#[derive(Clone, Copy, Debug, Hash, PartialEq, Eq, Coding, Hierarchy)]
#[extends(ExprReq, ExtHostReq)]
pub struct Inspect {
pub target: ExprTicket,
pub target: ExprTicket,
}
impl Request for Inspect {
type Response = Inspected;
type Response = Inspected;
}
#[derive(Clone, Copy, Debug, Hash, PartialEq, Eq, Coding, Hierarchy)]
#[extends(ExtHostReq)]
#[extendable]
pub enum ExprReq {
Inspect(Inspect),
Inspect(Inspect),
}
#[derive(Clone, Copy, Debug, Hash, PartialEq, Eq, Coding, Hierarchy)]
#[extends(ExtHostNotif)]
#[extendable]
pub enum ExprNotif {
Acquire(Acquire),
Release(Release),
Move(Move),
Acquire(Acquire),
Release(Release),
Move(Move),
}

View File

@@ -12,10 +12,10 @@ use crate::{ExtHostReq, HostExtReq};
#[extends(ExtHostReq)]
#[extendable]
pub enum IntReq {
InternStr(InternStr),
InternStrv(InternStrv),
ExternStr(ExternStr),
ExternStrv(ExternStrv),
InternStr(InternStr),
InternStrv(InternStrv),
ExternStr(ExternStr),
ExternStrv(ExternStrv),
}
/// replica -> master to intern a string on the master. Repeatable.
@@ -25,7 +25,7 @@ pub enum IntReq {
#[extends(IntReq, ExtHostReq)]
pub struct InternStr(pub Arc<String>);
impl Request for InternStr {
type Response = TStr;
type Response = TStr;
}
/// replica -> master to find the interned string corresponding to a key.
@@ -37,7 +37,7 @@ impl Request for InternStr {
#[extends(IntReq, ExtHostReq)]
pub struct ExternStr(pub TStr);
impl Request for ExternStr {
type Response = Arc<String>;
type Response = Arc<String>;
}
/// replica -> master to intern a vector of interned strings
///
@@ -48,7 +48,7 @@ impl Request for ExternStr {
#[extends(IntReq, ExtHostReq)]
pub struct InternStrv(pub Arc<Vec<TStr>>);
impl Request for InternStrv {
type Response = TStrv;
type Response = TStrv;
}
/// replica -> master to find the vector of interned strings corresponding to a
/// token
@@ -60,7 +60,7 @@ impl Request for InternStrv {
#[extends(IntReq, ExtHostReq)]
pub struct ExternStrv(pub TStrv);
impl Request for ExternStrv {
type Response = Arc<Vec<TStr>>;
type Response = Arc<Vec<TStr>>;
}
/// A substitute for an interned string in serialized datastructures.
@@ -77,13 +77,13 @@ pub struct TStrv(pub NonZeroU64);
#[extends(HostExtReq)]
pub struct Sweep;
impl Request for Sweep {
type Response = Retained;
type Response = Retained;
}
/// List of keys in this replica that couldn't be sweeped because local
/// datastructures reference their value.
#[derive(Clone, Debug, Coding)]
pub struct Retained {
pub strings: Vec<TStr>,
pub vecs: Vec<TStrv>,
pub strings: Vec<TStr>,
pub vecs: Vec<TStrv>,
}

View File

@@ -14,33 +14,33 @@ pub struct CharFilter(pub Vec<RangeInclusive<char>>);
#[derive(Clone, Debug, Coding, Hierarchy)]
#[extends(HostExtReq)]
pub struct LexExpr {
pub sys: SysId,
pub id: ParsId,
pub text: TStr,
pub pos: u32,
pub sys: SysId,
pub id: ParsId,
pub text: TStr,
pub pos: u32,
}
impl Request for LexExpr {
type Response = Option<OrcResult<LexedExpr>>;
type Response = Option<OrcResult<LexedExpr>>;
}
#[derive(Clone, Debug, Coding)]
pub struct LexedExpr {
pub pos: u32,
pub expr: TokenTree,
pub pos: u32,
pub expr: TokenTree,
}
#[derive(Clone, Debug, Coding, Hierarchy)]
#[extends(ExtHostReq)]
pub struct SubLex {
pub id: ParsId,
pub pos: u32,
pub id: ParsId,
pub pos: u32,
}
impl Request for SubLex {
type Response = Option<SubLexed>;
type Response = Option<SubLexed>;
}
#[derive(Clone, Debug, Coding)]
pub struct SubLexed {
pub pos: u32,
pub ticket: TreeTicket,
pub pos: u32,
pub ticket: TreeTicket,
}

View File

@@ -6,29 +6,29 @@ use crate::{TStr, TStrv};
#[derive(Clone, Debug, Coding)]
pub enum Location {
/// Location inaccessible. Locations are always debugging aids and never
/// mandatory.
None,
/// Associated with a slot when wrapped in an expression.
SlotTarget,
/// Used in functions to denote the generated code that carries on the
/// location of the call.
Inherit,
Gen(CodeGenInfo),
/// Range and file
SourceRange(SourceRange),
/// Range only, file implied. Most notably used by parsers
Range(Range<u32>),
/// Location inaccessible. Locations are always debugging aids and never
/// mandatory.
None,
/// Associated with a slot when wrapped in an expression.
SlotTarget,
/// Used in functions to denote the generated code that carries on the
/// location of the call.
Inherit,
Gen(CodeGenInfo),
/// Range and file
SourceRange(SourceRange),
/// Range only, file implied. Most notably used by parsers
Range(Range<u32>),
}
#[derive(Clone, Debug, Coding)]
pub struct SourceRange {
pub path: TStrv,
pub range: Range<u32>,
pub path: TStrv,
pub range: Range<u32>,
}
#[derive(Clone, Debug, Coding)]
pub struct CodeGenInfo {
pub generator: TStrv,
pub details: TStr,
pub generator: TStrv,
pub details: TStr,
}

View File

@@ -4,8 +4,8 @@ use crate::ExtHostNotif;
#[derive(Clone, Debug, Coding)]
pub enum LogStrategy {
StdErr,
File(String),
StdErr,
File(String),
}
#[derive(Clone, Debug, Coding, Hierarchy)]

View File

@@ -5,79 +5,82 @@ use orchid_api_derive::{Coding, Hierarchy};
use orchid_api_traits::Request;
use ordered_float::NotNan;
use crate::{Atom, Comment, ExtHostReq, HostExtReq, Location, OrcResult, Paren, ParsId, SysId, TStr, TStrv};
use crate::{
Atom, Comment, ExtHostReq, HostExtReq, Location, OrcResult, Paren, ParsId, SysId, TStr, TStrv,
};
#[derive(Clone, Copy, Debug, Coding, PartialEq, Eq, PartialOrd, Ord, Hash)]
pub struct MacroTreeId(pub NonZeroU64);
#[derive(Clone, Debug, Coding)]
pub struct MacroTree {
pub location: Location,
pub token: MacroToken,
pub location: Location,
pub token: MacroToken,
}
#[derive(Clone, Debug, Coding)]
pub enum MacroToken {
S(Paren, Vec<MacroTree>),
Name(TStrv),
Slot(MacroTreeId),
Lambda(Vec<MacroTree>, Vec<MacroTree>),
Ph(Placeholder),
Atom(Atom),
S(Paren, Vec<MacroTree>),
Name(TStrv),
Slot(MacroTreeId),
Lambda(Vec<MacroTree>, Vec<MacroTree>),
Ph(Placeholder),
Atom(Atom),
}
#[derive(Clone, Debug, Coding)]
pub struct MacroBlock {
pub priority: Option<NotNan<f64>>,
pub rules: Vec<MacroRule>,
pub priority: Option<NotNan<f64>>,
pub rules: Vec<MacroRule>,
}
#[derive(Clone, Debug, Coding)]
pub struct MacroRule {
pub location: Location,
pub comments: Vec<Comment>,
pub pattern: Vec<MacroTree>,
pub id: MacroId,
pub location: Location,
pub comments: Vec<Comment>,
pub pattern: Vec<MacroTree>,
pub id: MacroId,
}
/// A specific macro rule with a specific pattern across invocations
#[derive(Clone, Copy, Debug, Coding, PartialEq, Eq, Hash)]
pub struct MacroId(pub NonZeroU64);
/// After a pattern matches, this call executes the body of the macro. This request returns None
/// if an inner nested request raised an exception
/// After a pattern matches, this call executes the body of the macro. This
/// request returns None if an inner nested request raised an exception
#[derive(Clone, Debug, Coding, Hierarchy)]
#[extends(HostExtReq)]
pub struct ApplyMacro {
pub sys: SysId,
pub id: MacroId,
/// Recursion token
pub run_id: ParsId,
/// Must contain exactly the keys that were specified as placeholders in the pattern
pub params: HashMap<TStr, Vec<MacroTree>>,
pub sys: SysId,
pub id: MacroId,
/// Recursion token
pub run_id: ParsId,
/// Must contain exactly the keys that were specified as placeholders in the
/// pattern
pub params: HashMap<TStr, Vec<MacroTree>>,
}
impl Request for ApplyMacro {
type Response = Option<OrcResult<Vec<MacroTree>>>;
type Response = Option<OrcResult<Vec<MacroTree>>>;
}
#[derive(Clone, Debug, Coding, Hierarchy)]
#[extends(ExtHostReq)]
pub struct RunMacros {
pub run_id: ParsId,
pub query: Vec<MacroTree>,
pub run_id: ParsId,
pub query: Vec<MacroTree>,
}
impl Request for RunMacros {
type Response = Option<Vec<MacroTree>>;
type Response = Option<Vec<MacroTree>>;
}
#[derive(Clone, Debug, Coding)]
pub struct Placeholder {
pub name: TStr,
pub kind: PhKind,
pub name: TStr,
pub kind: PhKind,
}
#[derive(Clone, Copy, Debug, Coding)]
pub enum PhKind {
Scalar,
Vector { priority: u8, at_least_one: bool },
Scalar,
Vector { priority: u8, at_least_one: bool },
}

View File

@@ -11,11 +11,11 @@ pub struct ParsId(pub NonZeroU64);
#[derive(Clone, Debug, Coding, Hierarchy)]
#[extends(HostExtReq)]
pub struct ParseLine {
pub sys: SysId,
pub comments: Vec<Comment>,
pub exported: bool,
pub line: Vec<TokenTree>,
pub sys: SysId,
pub comments: Vec<Comment>,
pub exported: bool,
pub line: Vec<TokenTree>,
}
impl Request for ParseLine {
type Response = OrcResult<Vec<TokenTree>>;
type Response = OrcResult<Vec<TokenTree>>;
}

View File

@@ -25,63 +25,63 @@
use std::io::{Read, Write};
use orchid_api_derive::{Coding, Hierarchy};
use orchid_api_traits::{read_exact, write_exact, Channel, Decode, Encode, MsgSet, Request};
use orchid_api_traits::{Channel, Decode, Encode, MsgSet, Request, read_exact, write_exact};
use crate::{atom, expr, interner, lexer, logging, macros, parser, system, tree, vfs};
static HOST_INTRO: &[u8] = b"Orchid host, binary API v0\n";
pub struct HostHeader {
pub log_strategy: logging::LogStrategy,
pub log_strategy: logging::LogStrategy,
}
impl Decode for HostHeader {
fn decode<R: Read + ?Sized>(read: &mut R) -> Self {
read_exact(read, HOST_INTRO);
Self { log_strategy: logging::LogStrategy::decode(read) }
}
fn decode<R: Read + ?Sized>(read: &mut R) -> Self {
read_exact(read, HOST_INTRO);
Self { log_strategy: logging::LogStrategy::decode(read) }
}
}
impl Encode for HostHeader {
fn encode<W: Write + ?Sized>(&self, write: &mut W) {
write_exact(write, HOST_INTRO);
self.log_strategy.encode(write)
}
fn encode<W: Write + ?Sized>(&self, write: &mut W) {
write_exact(write, HOST_INTRO);
self.log_strategy.encode(write)
}
}
static EXT_INTRO: &[u8] = b"Orchid extension, binary API v0\n";
pub struct ExtensionHeader {
pub name: String,
pub systems: Vec<system::SystemDecl>,
pub name: String,
pub systems: Vec<system::SystemDecl>,
}
impl Decode for ExtensionHeader {
fn decode<R: Read + ?Sized>(read: &mut R) -> Self {
read_exact(read, EXT_INTRO);
Self { name: String::decode(read), systems: Vec::decode(read) }
}
fn decode<R: Read + ?Sized>(read: &mut R) -> Self {
read_exact(read, EXT_INTRO);
Self { name: String::decode(read), systems: Vec::decode(read) }
}
}
impl Encode for ExtensionHeader {
fn encode<W: Write + ?Sized>(&self, write: &mut W) {
write_exact(write, EXT_INTRO);
self.name.encode(write);
self.systems.encode(write)
}
fn encode<W: Write + ?Sized>(&self, write: &mut W) {
write_exact(write, EXT_INTRO);
self.name.encode(write);
self.systems.encode(write)
}
}
#[derive(Clone, Debug, Copy, Hash, PartialEq, Eq, PartialOrd, Ord, Coding)]
pub struct Ping;
impl Request for Ping {
type Response = ();
type Response = ();
}
/// Requests running from the extension to the host
#[derive(Clone, Coding, Hierarchy)]
#[extendable]
pub enum ExtHostReq {
Ping(Ping),
IntReq(interner::IntReq),
Fwd(atom::Fwd),
SysFwd(system::SysFwd),
ExprReq(expr::ExprReq),
SubLex(lexer::SubLex),
RunMacros(macros::RunMacros),
Ping(Ping),
IntReq(interner::IntReq),
Fwd(atom::Fwd),
SysFwd(system::SysFwd),
ExprReq(expr::ExprReq),
SubLex(lexer::SubLex),
RunMacros(macros::RunMacros),
}
/// Notifications sent from the extension to the host
@@ -89,93 +89,93 @@ pub enum ExtHostReq {
#[derive(Debug, Clone, Coding, Hierarchy)]
#[extendable]
pub enum ExtHostNotif {
ExprNotif(expr::ExprNotif),
Log(logging::Log),
ExprNotif(expr::ExprNotif),
Log(logging::Log),
}
pub struct ExtHostChannel;
impl Channel for ExtHostChannel {
type Notif = ExtHostNotif;
type Req = ExtHostReq;
type Notif = ExtHostNotif;
type Req = ExtHostReq;
}
/// Requests running from the host to the extension
#[derive(Clone, Debug, Coding, Hierarchy)]
#[extendable]
pub enum HostExtReq {
Ping(Ping),
SysReq(system::SysReq),
Sweep(interner::Sweep),
AtomReq(atom::AtomReq),
DeserAtom(atom::DeserAtom),
LexExpr(lexer::LexExpr),
ParseLine(parser::ParseLine),
GetMember(tree::GetMember),
VfsReq(vfs::VfsReq),
ApplyMacro(macros::ApplyMacro),
Ping(Ping),
SysReq(system::SysReq),
Sweep(interner::Sweep),
AtomReq(atom::AtomReq),
DeserAtom(atom::DeserAtom),
LexExpr(lexer::LexExpr),
ParseLine(parser::ParseLine),
GetMember(tree::GetMember),
VfsReq(vfs::VfsReq),
ApplyMacro(macros::ApplyMacro),
}
/// Notifications sent from the host to the extension
#[derive(Clone, Debug, Coding, Hierarchy)]
#[extendable]
pub enum HostExtNotif {
SystemDrop(system::SystemDrop),
AtomDrop(atom::AtomDrop),
/// The host can assume that after this notif is sent, a correctly written
/// extension will eventually exit.
Exit,
SystemDrop(system::SystemDrop),
AtomDrop(atom::AtomDrop),
/// The host can assume that after this notif is sent, a correctly written
/// extension will eventually exit.
Exit,
}
pub struct HostExtChannel;
impl Channel for HostExtChannel {
type Notif = HostExtNotif;
type Req = HostExtReq;
type Notif = HostExtNotif;
type Req = HostExtReq;
}
/// Message set viewed from the extension's perspective
pub struct ExtMsgSet;
impl MsgSet for ExtMsgSet {
type In = HostExtChannel;
type Out = ExtHostChannel;
type In = HostExtChannel;
type Out = ExtHostChannel;
}
/// Message Set viewed from the host's perspective
pub struct HostMsgSet;
impl MsgSet for HostMsgSet {
type In = ExtHostChannel;
type Out = HostExtChannel;
type In = ExtHostChannel;
type Out = HostExtChannel;
}
#[cfg(test)]
mod tests {
use orchid_api_traits::enc_vec;
use ordered_float::NotNan;
use orchid_api_traits::enc_vec;
use ordered_float::NotNan;
use super::*;
use super::*;
#[test]
fn host_header_enc() {
let hh = HostHeader { log_strategy: logging::LogStrategy::File("SomeFile".to_string()) };
let mut enc = &enc_vec(&hh)[..];
eprintln!("Encoded to {enc:?}");
HostHeader::decode(&mut enc);
assert_eq!(enc, []);
}
#[test]
fn host_header_enc() {
let hh = HostHeader { log_strategy: logging::LogStrategy::File("SomeFile".to_string()) };
let mut enc = &enc_vec(&hh)[..];
eprintln!("Encoded to {enc:?}");
HostHeader::decode(&mut enc);
assert_eq!(enc, []);
}
#[test]
fn ext_header_enc() {
let eh = ExtensionHeader {
name: "my_extension".to_string(),
systems: vec![system::SystemDecl {
id: system::SysDeclId(1.try_into().unwrap()),
name: "misc".to_string(),
depends: vec!["std".to_string()],
priority: NotNan::new(1f64).unwrap(),
}],
};
let mut enc = &enc_vec(&eh)[..];
eprintln!("Encoded to {enc:?}");
ExtensionHeader::decode(&mut enc);
assert_eq!(enc, [])
}
#[test]
fn ext_header_enc() {
let eh = ExtensionHeader {
name: "my_extension".to_string(),
systems: vec![system::SystemDecl {
id: system::SysDeclId(1.try_into().unwrap()),
name: "misc".to_string(),
depends: vec!["std".to_string()],
priority: NotNan::new(1f64).unwrap(),
}],
};
let mut enc = &enc_vec(&eh)[..];
eprintln!("Encoded to {enc:?}");
ExtensionHeader::decode(&mut enc);
assert_eq!(enc, [])
}
}

View File

@@ -19,21 +19,21 @@ pub struct SysId(pub NonZeroU16);
/// extension header, so it cannot rely on the interner.
#[derive(Debug, Clone, Coding)]
pub struct SystemDecl {
/// ID of the system, unique within the library
pub id: SysDeclId,
/// This can be depended upon. Exactly one of each kind will be loaded
pub name: String,
/// If multiple instances of a system are found, the highest priority will be
/// used. This can be used for version counting, but also for fallbacks if a
/// negative number is found.
///
/// Systems cannot depend on specific versions and older versions of systems
/// are never loaded. Compatibility can be determined on a per-system basis
/// through an algorithm chosen by the provider.
pub priority: NotNan<f64>,
/// List of systems needed for this one to work correctly. These will be
/// looked up, and an error produced if they aren't found.
pub depends: Vec<String>,
/// ID of the system, unique within the library
pub id: SysDeclId,
/// This can be depended upon. Exactly one of each kind will be loaded
pub name: String,
/// If multiple instances of a system are found, the highest priority will be
/// used. This can be used for version counting, but also for fallbacks if a
/// negative number is found.
///
/// Systems cannot depend on specific versions and older versions of systems
/// are never loaded. Compatibility can be determined on a per-system basis
/// through an algorithm chosen by the provider.
pub priority: NotNan<f64>,
/// List of systems needed for this one to work correctly. These will be
/// looked up, and an error produced if they aren't found.
pub depends: Vec<String>,
}
/// Host -> extension; instantiate a system according to its [SystemDecl].
@@ -43,26 +43,26 @@ pub struct SystemDecl {
#[derive(Clone, Debug, Coding, Hierarchy)]
#[extends(SysReq, HostExtReq)]
pub struct NewSystem {
/// ID of the system
pub system: SysDeclId,
/// ID of the system instance, unique for the host
pub id: SysId,
/// Instance IDs for dependencies, in the order that the names appear in the
/// declaration
pub depends: Vec<SysId>,
/// ID of the system
pub system: SysDeclId,
/// ID of the system instance, unique for the host
pub id: SysId,
/// Instance IDs for dependencies, in the order that the names appear in the
/// declaration
pub depends: Vec<SysId>,
}
impl Request for NewSystem {
type Response = SystemInst;
type Response = SystemInst;
}
#[derive(Clone, Debug, Coding)]
pub struct SystemInst {
/// The set of possible starting characters of tokens the lexer of this system
/// can process. The lexer will notify this system if it encounters one of
/// these characters.9
pub lex_filter: CharFilter,
pub line_types: Vec<TStr>,
pub const_root: HashMap<TStr, MemberKind>,
/// The set of possible starting characters of tokens the lexer of this system
/// can process. The lexer will notify this system if it encounters one of
/// these characters.9
pub lex_filter: CharFilter,
pub line_types: Vec<TStr>,
pub const_root: HashMap<TStr, MemberKind>,
}
#[derive(Clone, Debug, Coding, Hierarchy)]
@@ -73,20 +73,20 @@ pub struct SystemDrop(pub SysId);
#[extends(SysReq, HostExtReq)]
pub struct SysFwded(pub SysId, pub Vec<u8>);
impl Request for SysFwded {
type Response = Vec<u8>;
type Response = Vec<u8>;
}
#[derive(Clone, Debug, Coding, Hierarchy)]
#[extends(ExtHostReq)]
pub struct SysFwd(pub SysId, pub Vec<u8>);
impl Request for SysFwd {
type Response = Vec<u8>;
type Response = Vec<u8>;
}
#[derive(Clone, Debug, Coding, Hierarchy)]
#[extends(HostExtReq)]
#[extendable]
pub enum SysReq {
NewSystem(NewSystem),
SysFwded(SysFwded),
NewSystem(NewSystem),
SysFwded(SysFwded),
}

View File

@@ -7,7 +7,7 @@ use orchid_api_traits::Request;
use ordered_float::NotNan;
use crate::{
Atom, Expression, HostExtReq, Location, MacroBlock, OrcError, Placeholder, SysId, TStr, TStrv,
Atom, Expression, HostExtReq, Location, MacroBlock, OrcError, Placeholder, SysId, TStr, TStrv,
};
/// A token tree from a lexer recursion request. Its lifetime is the lex call,
@@ -22,42 +22,42 @@ pub struct TreeTicket(pub NonZeroU64);
#[derive(Clone, Debug, Coding)]
pub struct TokenTree {
pub token: Token,
pub range: Range<u32>,
pub token: Token,
pub range: Range<u32>,
}
#[derive(Clone, Debug, Coding)]
pub enum Token {
/// Lambda function head, from the opening \ until the beginning of the body.
LambdaHead(Vec<TokenTree>),
/// A name segment or an operator.
Name(TStr),
/// ::
NS,
/// Line break.
BR,
/// ( Round parens ), [ Square brackets ] or { Curly braces }
S(Paren, Vec<TokenTree>),
/// A new atom
Atom(Atom),
/// Anchor to insert a subtree
Slot(TreeTicket),
/// A static compile-time error returned by failing lexers if
/// the rest of the source is likely still meaningful
Bottom(Vec<OrcError>),
/// A comment
Comment(Arc<String>),
/// Placeholder
Ph(Placeholder),
/// Macro block head
Macro(Option<NotNan<f64>>),
/// Lambda function head, from the opening \ until the beginning of the body.
LambdaHead(Vec<TokenTree>),
/// A name segment or an operator.
Name(TStr),
/// ::
NS,
/// Line break.
BR,
/// ( Round parens ), [ Square brackets ] or { Curly braces }
S(Paren, Vec<TokenTree>),
/// A new atom
Atom(Atom),
/// Anchor to insert a subtree
Slot(TreeTicket),
/// A static compile-time error returned by failing lexers if
/// the rest of the source is likely still meaningful
Bottom(Vec<OrcError>),
/// A comment
Comment(Arc<String>),
/// Placeholder
Ph(Placeholder),
/// Macro block head
Macro(Option<NotNan<f64>>),
}
#[derive(Copy, Clone, Debug, Hash, PartialEq, Eq, Coding)]
pub enum Paren {
Round,
Square,
Curly,
Round,
Square,
Curly,
}
#[derive(Copy, Clone, Debug, Hash, PartialEq, Eq, PartialOrd, Ord, Coding)]
@@ -65,46 +65,46 @@ pub struct TreeId(pub NonZeroU64);
#[derive(Clone, Debug, Coding)]
pub struct Item {
pub location: Location,
pub comments: Vec<Comment>,
pub kind: ItemKind,
pub location: Location,
pub comments: Vec<Comment>,
pub kind: ItemKind,
}
#[derive(Clone, Debug, Coding)]
pub enum ItemKind {
Member(Member),
Macro(MacroBlock),
Export(TStr),
Import(TStrv),
Member(Member),
Macro(MacroBlock),
Export(TStr),
Import(TStrv),
}
#[derive(Clone, Debug, Coding)]
pub struct Comment {
pub text: TStr,
pub location: Location,
pub text: TStr,
pub location: Location,
}
#[derive(Clone, Debug, Coding)]
pub struct Member {
pub name: TStr,
pub kind: MemberKind,
pub name: TStr,
pub kind: MemberKind,
}
#[derive(Clone, Debug, Coding)]
pub enum MemberKind {
Const(Expression),
Module(Module),
Lazy(TreeId),
Const(Expression),
Module(Module),
Lazy(TreeId),
}
#[derive(Clone, Debug, Coding)]
pub struct Module {
pub items: Vec<Item>,
pub items: Vec<Item>,
}
#[derive(Clone, Copy, Debug, Coding, Hierarchy)]
#[extends(HostExtReq)]
pub struct GetMember(pub SysId, pub TreeId);
impl Request for GetMember {
type Response = MemberKind;
type Response = MemberKind;
}

View File

@@ -14,34 +14,34 @@ pub struct VfsId(pub NonZeroU16);
#[derive(Clone, Debug, Coding)]
pub enum Loaded {
Code(String),
Collection(Vec<TStr>),
Code(String),
Collection(Vec<TStr>),
}
#[derive(Clone, Debug, Coding, Hierarchy)]
#[extends(VfsReq, HostExtReq)]
pub struct VfsRead(pub SysId, pub VfsId, pub Vec<TStr>);
impl Request for VfsRead {
type Response = OrcResult<Loaded>;
type Response = OrcResult<Loaded>;
}
#[derive(Clone, Debug, Coding)]
pub enum EagerVfs {
Lazy(VfsId),
Eager(HashMap<TStr, EagerVfs>),
Lazy(VfsId),
Eager(HashMap<TStr, EagerVfs>),
}
#[derive(Clone, Debug, Coding, Hierarchy)]
#[extends(VfsReq, HostExtReq)]
pub struct GetVfs(pub SysId);
impl Request for GetVfs {
type Response = EagerVfs;
type Response = EagerVfs;
}
#[derive(Clone, Debug, Coding, Hierarchy)]
#[extends(HostExtReq)]
#[extendable]
pub enum VfsReq {
GetVfs(GetVfs),
VfsRead(VfsRead),
GetVfs(GetVfs),
VfsRead(VfsRead),
}