{"id":30195172,"url":"https://github.com/kiebor81/embers","last_synced_at":"2026-01-19T20:05:50.333Z","repository":{"id":309020787,"uuid":"1034901756","full_name":"kiebor81/embers","owner":"kiebor81","description":"Embers is a portmanteau of \"embedded\" and \"ruby script\". This is an embeddable Ruby interpreter for C#.","archived":false,"fork":false,"pushed_at":"2026-01-18T10:45:30.000Z","size":845,"stargazers_count":3,"open_issues_count":0,"forks_count":0,"subscribers_count":0,"default_branch":"main","last_synced_at":"2026-01-18T10:58:11.657Z","etag":null,"topics":["csharp","dsl","dsl-syntax","embbeded-system","game-engine","godot-engine","interpreter","parser","ruby","runtime","scripting-engine","scripting-language","scripts","unity-engine"],"latest_commit_sha":null,"homepage":"","language":"C#","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/kiebor81.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null,"zenodo":null,"notice":null,"maintainers":null,"copyright":null,"agents":null,"dco":null,"cla":null}},"created_at":"2025-08-09T08:10:48.000Z","updated_at":"2026-01-18T10:45:34.000Z","dependencies_parsed_at":"2025-08-09T10:26:45.738Z","dependency_job_id":"3fd06716-8699-48d0-8871-61ce9aad3aec","html_url":"https://github.com/kiebor81/embers","commit_stats":null,"previous_names":["kiebor81/embers"],"tags_count":7,"template":false,"template_full_name":null,"purl":"pkg:github/kiebor81/embers","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/kiebor81%2Fembers","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/kiebor81%2Fembers/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/kiebor81%2Fembers/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/kiebor81%2Fembers/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/kiebor81","download_url":"https://codeload.github.com/kiebor81/embers/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/kiebor81%2Fembers/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":28583645,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-01-19T19:46:29.903Z","status":"ssl_error","status_checked_at":"2026-01-19T19:45:54.560Z","response_time":67,"last_error":"SSL_read: unexpected eof while reading","robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":false,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["csharp","dsl","dsl-syntax","embbeded-system","game-engine","godot-engine","interpreter","parser","ruby","runtime","scripting-engine","scripting-language","scripts","unity-engine"],"created_at":"2025-08-13T04:01:40.587Z","updated_at":"2026-01-19T20:05:50.296Z","avatar_url":"https://github.com/kiebor81.png","language":"C#","funding_links":[],"categories":[],"sub_categories":[],"readme":"# Embers\n\n[![NuGet](https://img.shields.io/nuget/v/Embers.Runtime.svg)](https://www.nuget.org/packages/Embers.Runtime)\n[![License](https://img.shields.io/badge/license-MIT-blue.svg)](LICENSE)\n[![Build](https://github.com/kiebor81/embers/actions/workflows/build-and-test.yml/badge.svg)](https://github.com/kiebor81/embers/actions/workflows/build-and-test.yml)\n[![Release](https://github.com/kiebor81/embers/actions/workflows/release.yml/badge.svg)](https://github.com/kiebor81/embers/actions/workflows/release.yml)\n\n\u003cp align=\"center\"\u003e\n  \u003cimg src=\"Assets/icon-512.png\" alt=\"Embers logo\" width=\"256\" /\u003e\n\u003c/p\u003e\n\n**Embers** (Embedded Ruby Script) is a compact, embeddable Ruby-inspired interpreter written in C# for .NET. It is designed for applications that need a lightweight, scriptable runtime (e.g. games, tools, or plugin systems) without the overhead of creating and maintaining a complex, custom implementation.\n\nIn a nutshell:\n\u003e *Embers is intended for developers who want a structured scripting language integrated directly into their .NET applications, without outsourcing control to an external runtime.*\n\nEmbers is **not** a 1:1 implementation of Ruby in .NET. It is not IronRuby or a drop-in replacement for existing Ruby runtimes. Instead, it provides a deliberately scoped, Ruby-like language with familiar syntax and semantics, prioritising embeddability, extensibility, and host integration over parity-completeness.\n\nEmbers is an experimental runtime, inspired by and building upon earlier projects that are no longer actively maintained:\n- [Embers by Joy-less](https://github.com/Joy-less/Embers)\n- [RubySharp by AjLopez](https://github.com/ajlopez/RubySharp)\n\nWhile a large portion of commonly used functions from Ruby's StdLib are present in the solution, full type binding and language coverage are intentionally incomplete; either out of scope or reserved for future development. Embers follows a strict architectural pattern, making it straightforward to extend, with features evolving and maturing as required.\n\n## Overview\n\nEmbers is built around a clean, minimal core with the goal of executing Ruby-like scripts in constrained or embedded environments. The interpreter features:\n\n- A recursive descent parser for Ruby-like syntax\n- Lexical analysis via a custom `Lexer`\n- A virtual execution engine (`Machine`)\n- Context-sensitive execution (`Context`, `BlockContext`)\n- Robust exception model mirroring Ruby's error semantics\n- Embeddability and interoperability within .NET 9+ projects\n\n---\n\n## Design\n\nThe following section is primarily useful for contributors or developers extending Embers, or those interested in the architectural patterns and topography of the solution.\n\n### Execution Flow\n\n```mermaid\nflowchart TD\n    A[Embers Script]\n    B[Lexer\u003cbr/\u003eEmbers.Compiler.Lexer]\n    C[Parser\u003cbr/\u003eEmbers.Compiler.Parser]\n    D[Expression Tree\u003cbr/\u003eIExpression Instances]\n    E[Machine\u003cbr/\u003eEmbers.Machine]\n    F[Context \u0026 Scope\u003cbr/\u003eContext / BlockContext]\n    G[Execution\u003cbr/\u003eVisitor-Style Interpreter]\n    H[Result or Side Effects]\n\n    A --\u003e B\n    B --\u003e C\n    C --\u003e D\n    D --\u003e E\n    E --\u003e F\n    E --\u003e G\n    F --\u003e G\n    G --\u003e H\n```\n\n### Logical Topography\n\n```mermaid\ngraph TD\n    A[Embers]\n    \n    A1[Compiler]\n    A2[Language]\n    A3[Host]\n    A4[Security]\n    A5[Exceptions]\n    A6[Functions]\n\n    A --\u003e A1\n    A --\u003e A2\n    A --\u003e A3\n    A --\u003e A4\n    A --\u003e A5\n    A --\u003e A6\n\n    A1 --\u003e A1_Lexer[Lexer]\n    A1 --\u003e A1_Parser[Parser]\n    A1 --\u003e A1_Token[Token, TokenType, Streams]\n\n    A2 --\u003e A2_Expressions[IExpression + AST Types]\n    A2 --\u003e A2_Context[Context / BlockContext]\n    A2 --\u003e A2_ObjectModel[DynamicObject, ClassDef, etc.]\n\n    A3 --\u003e A3_Function[HostFunction]\n    A3 --\u003e A3_Attribute[HostFunctionAttribute]\n    A3 --\u003e A3_Injector[HostFunctionInjector]\n\n    A4 --\u003e A4_TypeAccess[TypeAccessPolicy]\n\n    A5 --\u003e A5_BuiltinErrors[NameError, TypeError, NoMethodError, ...]\n\n    A6 --\u003e A6_IFunction[IFunction Interface]\n    A6 --\u003e A6_CoreFunctions[Built-in Function Types]\n```\n\n## Projects\n\n- `Embers`: Core interpreter (main focus)\n- `Embers.Console`: Example CLI host for executing embers (`.rb`, `.rs`, `.ers`, `.emb`) scripts or launching an interactive REPL\n- `Embers.ISE`: Rudimentary ISE for Embers, illustrating self documentation, host injection, and real-time policy change\n- `Embers.Tests`: Unit and integration tests covering Embers' functionality\n- `MyLib`: DSL playground and test library.\n\n## Design Goals\n\n- **Portability**: Target .NET with minimal external dependencies\n- **Embedding First**: Built to be embedded in other applications, not just run standalone\n- **Ruby-Inspired**: Implements a Ruby-like language subset with idiomatic constructs\n- **Simplicity**: Clear structure with low cognitive overhead for contributors\n- **Performance**: Designed for fast startup and predictable execution in memory-limited contexts\n\n## Key Components\n\n- **Lexer** (`Compiler/Lexer.cs`): Tokenizes input strings into operators, literals, variables, etc.\n- **Parser** (`Compiler/Parser.cs`): Converts tokens into expression trees (`IExpression`)\n- **Machine** (`Machine.cs`): Executes expression trees using a visitor-style interpreter\n- **Context \u0026 BlockContext**: Manages variable scopes, closures, and execution frames\n- **Registration** (`Registration.cs`): Handles registration of built-in methods and object types\n- **StdLib System** (`StdLib/`): Reflection-based standard library with automatic function discovery and registration\n- **Exceptions**: Rich error handling mimicking Ruby (e.g., `NameError`, `NoMethodError`, `SyntaxError`)\n\n## Usage\n\n### Embedding the Interpreter\n\nYou can embed Embers in any .NET project:\n\n```csharp\nvar machine = new Machine();\nmachine.Execute(\"puts 'Hello from Embers!'\");\n```\n\n#### Execution Methods\n\nThe `Machine` exposes three execution entry points:\n\n- `ExecuteText(string code)`  \n  Parses and executes Embers code directly from a string.\n\n- `ExecuteFile(string path)`  \n  Parses and executes an Embers script from a file on disk.\n\n- `Execute(string input)`  \n  Convenience method that proxies to `ExecuteFile` or `ExecuteText` based on whether the input resolves to an existing file path.\n\n**Note**:  \n`Execute` determines whether to treat its input as a file path using `File.Exists`.\n\nIf the input appears to be a file path (e.g. contains path separators, file extensions, or is rooted) but does not resolve to an existing file, `Execute` will throw a `FileNotFoundException` rather than attempting to execute it as code.\n\n\u003e For explicit intent and clarity, prefer calling `ExecuteText` or `ExecuteFile` directly.\n\n---\n\n## Script Syntax\n\nEmbers supports a [substantial Ruby-like syntax](/Docs/Grammar.md):\n\n```ruby\ndef square(x)\n  x * x\nend\n\nputs square(10)  # =\u003e 100\n```\n\nSupports:\n\n- Method definitions\n- Variable assignments\n- Control structures (`if`, `unless`, `while`, etc.)\n- Class and instance variables (`@foo`, `@@bar`)\n- Exceptions (`raise`, `begin/rescue/ensure/end`)\n- Instance methods on native types (e.g., `5.abs`, `3.14.ceil`, `now.year`)\n- C# interop via direct .NET type access (e.g., `System.DateTime.Now`)\n\n**Note**:\nAvailability of .NET types depends on the configured type access policy.\n\n---\n\n## Security Configuration\n\nEmbers' C# interop is powerful, but allowing any foreign code execution complete and unfettered access to .NET at runtime, can be equally dangerous and allows for potential malicious code injection. To combat this, Embers includes a host-level **type access policy** system to restrict which .NET types and namespaces can be accessed or exposed to the interpreter. This system is defined in `Embers.Security.TypeAccessPolicy` and enforces security through two modes:\n\n### Security Modes\n\n```csharp\npublic enum SecurityMode\n{\n    Unrestricted,    // All types are accessible\n    WhitelistOnly    // Only whitelisted types and namespaces are allowed\n}\n```\n\n- **Unrestricted**: Default mode. All types are permitted.\n- **WhitelistOnly**: Only explicitly allowed types or namespaces can be accessed.\n\n### Under the Hood\n\nAllowed types and namespaces are configured in the policy:\n\n```csharp\nTypeAccessPolicy.SetPolicy(new[]\n{\n    \"MyApp.API.SafeClass\",\n    \"MyApp.Scripting.*\"\n}, SecurityMode.WhitelistOnly);\n```\n\nThis example:\n- Allows the specific type `MyApp.API.SafeClass`\n- Allows all types under the `MyApp.Scripting` namespace\n\n### Fine-Grained Controls\n\nPolicy can be manipulated at runtime by your host application:\n\n```csharp\nTypeAccessPolicy.AddType(\"MyApp.Tools.ScriptableAction\");\nTypeAccessPolicy.AddNamespace(\"MyApp.Sandbox\");\n```\n\nTo reset all policies:\n\n```csharp\nTypeAccessPolicy.Clear();\n```\n\n### Configuring the Policy\n\n`TypeAccessPolicy` is internal only. For embedded, pre-shipped, or user-authored scripts, it is strongly recommended to use `WhitelistOnly` mode.\n\nThe policy is governed by the machine (runtime) instance via the public API:\n\n```csharp\n        /// \u003csummary\u003e\n        /// Sets the type access policy.\n        /// Allowed entries are a list of full type names that are allowed to be accessed.\n        /// Provide allowed entries as a list of strings where final character '.' implies a namespace.\n        /// \u003c/summary\u003e\n        /// \u003cparam name=\"allowedEntries\"\u003eThe allowed entries.\u003c/param\u003e\n        public void SetTypeAccessPolicy(IEnumerable\u003cstring\u003e allowedEntries, SecurityMode mode = SecurityMode.WhitelistOnly)\n        {\n            TypeAccessPolicy.SetPolicy(allowedEntries, mode);\n        }\n\n        /// \u003csummary\u003e\n        /// Allows the type.\n        /// \u003c/summary\u003e\n        /// \u003cparam name=\"fullTypeName\"\u003eFull name of the type.\u003c/param\u003e\n        public void AllowType(string fullTypeName)\n        {\n            Security.TypeAccessPolicy.AddType(fullTypeName);\n        }\n\n        /// \u003csummary\u003e\n        /// Allows the namespace.\n        /// \u003c/summary\u003e\n        /// \u003cparam name=\"prefix\"\u003eThe prefix.\u003c/param\u003e\n        public void AllowNamespace(string prefix)\n        {\n            Security.TypeAccessPolicy.AddNamespace(prefix);\n        }\n\n        /// \u003csummary\u003e\n        /// Clears the security policy.\n        /// \u003c/summary\u003e\n        public void ClearSecurityPolicy()\n        {\n            Security.TypeAccessPolicy.Clear();\n        }\n```\n\n### Runtime Enforcement\n\nAny type lookups during execution check against this policy:\n\n```csharp\nif (!TypeAccessPolicy.IsAllowed(fullTypeName))\n    throw new TypeAccessError(...);\n```\n\nThis ensures unregistered types are never exposed to interpreted code under `WhitelistOnly` mode.\n\n---\n\n## Building a Custom DSL\n\nEmbers enables you to define host-side .NET methods as callable functions within Ruby-like scripts. This is the foundation for building domain-specific languages (DSLs) tailored to your application's runtime while encapsulating host functionality behind a stable scripting interface.\n\n### Define a Host Function\n\nTo define an Embers-callable host function:\n\n1. Inherit from `HostFunction` (defined in `Embers.Host.HostFunction`)\n2. Decorate the class with `[HostFunction(...)]` and provide one or more Embers-visible names\n3. Implement the `Apply` method\n\n#### Example\n\n```csharp\nusing Embers.Host;\nusing Embers.Language;\n\n[HostFunction(\"hello\")]\ninternal class HelloFunction : HostFunction\n{\n    public override object Apply(DynamicObject self, Context context, IList\u003cobject\u003e values)\n    {\n        Console.WriteLine(\"Hello from Embers!\");\n        return null;\n    }\n}\n```\n\n### Register Functions with the Machine\n\nUse `HostFunctionInjector` to automatically discover and register all `[HostFunction]` classes:\n\n```csharp\nMachine machine = new();\nmachine.InjectFromCallingAssembly();\nmachine.ExecuteText(\"hello\"); // prints \"Hello from Embers!\"\n```\n\nYou can also inject from a specific assembly or all referenced ones if you are following a plugin architecture or have separated your DSL across projects:\n\n```csharp\nmachine.InjectFromAssembly(typeof(MyDSLClass).Assembly);\nmachine.InjectFromReferencedAssemblies();\n```\n\n### Multiple Names and Composition\n\nYou can expose a function under multiple aliases:\n\n```csharp\n[HostFunction(\"guid\", \"generate_guid\")]\ninternal class GuidFunction : HostFunction\n{\n    public override object Apply(DynamicObject self, Context context, IList\u003cobject\u003e values)\n    {\n        return Guid.NewGuid().ToString();\n    }\n}\n```\n\nThen from Embers:\n\n```ruby\nputs guid\nputs generate_guid\n```\n\n---\n\n## Function Documentation \u0026 Introspection\n\nEmbers supports method-level documentation attributes for both host functions and standard library functions. These attributes are intended to support tooling such as REPL help, documentation generation, and editor integrations.\n\nDocumentation metadata is extracted at runtime via reflection and does not affect execution behaviour. All documentation attributes are optional; functions without annotations will still be discovered and executed normally.\n\n### Supported Attributes\n\nThe following attributes can be applied to the `Apply` method of any `IFunction` implementation:\n\n`CommentsAttribute`\n\nProvides high-level descriptive text for the function.\n\ne.g.\n\n```csharp\n[Comments(\n    \"Prints a message to the host output.\",\n    \"Primarily intended for debugging or logging.\"\n)]\n```\n\n`ArgumentsAttribute`\n\nDescribes parameter names and expected types.\n\ne.g.\n\n```csharp\n[Arguments(\n    ParamNames = new[] { \"message\" },\n    ParamTypes = new[] { typeof(string) }\n)]\n```\n\n`ReturnsAttribute`\n\nSpecifies the return type for documentation purposes.\n\ne.g.\n\n```csharp\n[Returns(ReturnType = typeof(void))]\n```\n\nComplete example:\n\n```csharp\n[HostFunction(\"hello\")]\ninternal class HelloFunction : HostFunction\n{\n    [Comments(\"Prints a greeting message.\")]\n    [Arguments(ParamNames = new[] { \"message\" }, ParamTypes = new[] { typeof(string) })]\n    [Returns(ReturnType = typeof(void))]\n    public override object Apply(DynamicObject self, Context context, IList\u003cobject\u003e values)\n    {\n        Console.WriteLine($\"Hello {values[0]}\");\n        return null;\n    }\n}\n```\n\n### Runtime Discovery\n\nAt runtime, host applications can scan all loaded assemblies to extract documentation metadata from functions. This is performed by the `FunctionScanner` and produces a structured representation of available functions and their signatures.\n\nThis mechanism is intended for tooling and introspection and may be used by hosts to implement features such as:\n- REPL `help` commands\n- Auto-generated documentation\n- Editor hints or completions\n\n`FunctionScanner.ScanFunctionDocumentation()` returns a dictionary mapping function aliases to structured documentation data (comments, arguments, and return information).\n\nThe format and presentation of this information should be entirely host-defined when consumed.\n\nAn example `help` function may resemble\n\n```csharp\n// Example host-defined help command using function annotations\n[HostFunction(\"help\")]\ninternal class HelpFunction : HostFunction\n{\n    // add attributes for self documentation\n    [Comments(\"Provides method look-up and documentation.\", \"Prints results to console.\")]\n    [Arguments(ParamNames = new[] { \"method_name\" }, ParamTypes = new[] { typeof(string) })]\n    [Returns(ReturnType = typeof(void))]\n    public override object Apply(DynamicObject self, Context context, IList\u003cobject\u003e values)\n    {\n\n        var documentation_dict = Annotations.FunctionScanner.ScanFunctionDocumentation();\n\n        IEnumerable\u003cstring\u003e keysToDisplay;\n\n        // did user provide a method name as string to lookup?\n        // format help \"\u003c\u003cMETHOD_NAME\u003e\u003e\"\n        // if they did, find that method and return\n        // otherwise get the full list\n        if (values == null || values.Count == 0)\n        {\n            keysToDisplay = documentation_dict.Keys;\n        }\n        else\n        {\n            var lookupKey = values[0].ToString();\n            keysToDisplay = documentation_dict.Keys.Where(k =\u003e \n            {\n                var keyParts = k.Split(',').Select(p =\u003e p.Trim());\n                return keyParts.Contains(lookupKey);\n            });\n        }\n\n        // extract documentation and write to console output\n        foreach (var key in keysToDisplay)\n        {\n            System.Console.WriteLine($\"Method: {key}\");\n            var doc = documentation_dict[key];\n            \n            if (!string.IsNullOrEmpty(doc.Comments))\n                System.Console.WriteLine($\"  Comments: {doc.Comments}\");\n            \n            if (!string.IsNullOrEmpty(doc.Arguments))\n                System.Console.WriteLine($\"  Arguments: {doc.Arguments}\");\n            \n            if (!string.IsNullOrEmpty(doc.Returns))\n                System.Console.WriteLine($\"  Returns: {doc.Returns}\");\n\n            System.Console.WriteLine(\"\");\n\n        }\n\n        return null;\n    }\n}\n```\n\nThis mechanism is intended to enable rich developer tooling without coupling Embers to any specific user interface or documentation format.\n\n#### Exclude From Discovery\n\nTo exclude a function from this mechanism, `ScannerIgnoreAttribute` can be applied to the function class.\n\ne.g.\n\n```csharp\n[HostFunction(\"awesome\"), ScannerIgnore]\ninternal class AwesomeFunction : HostFunction { }\n```\n\nThis is useful for internal, experimental, iterative, or implementation-detail functions that should not appear in tooling output.\n\n---\n\n## StdLib Function Registration\n\nEmbers includes a reflection-based standard library system for automatic function discovery and registration. Functions can be registered as global methods or as instance methods on native types (Ruby types mapped onto underlying C# representations).\n\n### Define a StdLib Function\n\n1. Inherit from your function base class\n2. Decorate with `[StdLib(...)]` attribute\n3. Specify target types for instance method registration\n\n#### Global Function Example\n\n```csharp\nusing Embers.StdLib;\n\n[StdLib(\"abs\")]\npublic class AbsFunction : StdFunction\n{\n    public object Apply(Context context, IList\u003cobject\u003e values)\n    {\n        var num = values[0];\n        return num switch\n        {\n            int i =\u003e Math.Abs(i),\n            double d =\u003e Math.Abs(d),\n            _ =\u003e throw new TypeError($\"Invalid type for abs: {num?.GetType()}\")\n        };\n    }\n}\n```\n\n#### Instance Method Example\n\nRegister a function on multiple types using `TargetTypes`:\n\n```csharp\n[StdLib(\"abs\", TargetTypes = new[] { \"Fixnum\", \"Float\" })]\npublic class AbsFunction : StdFunction\n{\n    public object Apply(Context context, IList\u003cobject\u003e values)\n    {\n        // values[0] contains the receiver (self)\n        var num = values[0];\n        return num switch\n        {\n            int i =\u003e Math.Abs(i),\n            double d =\u003e Math.Abs(d),\n            _ =\u003e throw new TypeError($\"Invalid type for abs: {num?.GetType()}\")\n        };\n    }\n}\n```\n\nNow callable as both global and instance methods:\n\n```ruby\nabs(-5)      # =\u003e 5 (global)\n(-5).abs     # =\u003e 5 (instance method on Fixnum)\n(-3.14).abs  # =\u003e 3.14 (instance method on Float)\n```\n\n### Native Types\n\nEmbers maps Ruby types to C# types through `NativeClass`:\n\n- **Fixnum** → `int` / `long`\n- **Float** → `double`\n- **String** → `string`\n- **Array** → `List\u003cobject\u003e`\n- **Hash** → `Dictionary\u003cobject, object\u003e`\n- **DateTime** → `System.DateTime`\n- **NilClass** → `null`\n- **Range** → `Range`\n\n### Automatic Discovery\n\nThe `StdLibRegistry` automatically discovers all `[StdLib]` decorated functions at runtime:\n\n```csharp\nvar machine = new Machine();\n// StdLib functions are automatically registered during Machine initialization\nmachine.ExecuteText(\"puts 5.abs\");     // =\u003e 5\nmachine.ExecuteText(\"puts (-10).abs\"); // =\u003e 10\n```\n\nFor more details and if you would like to help build on Embers through contributing StdLib functions, see [STDLIB.md](/Docs/STDLIB.md).\n\n---\n\n## Practical Use Cases\n\nEmbers is designed for embedding into diverse .NET applications. For in-depth examples, see [Examples](/Docs/Examples.md)\n\n---\n\n## License\n\nMIT License\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fkiebor81%2Fembers","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fkiebor81%2Fembers","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fkiebor81%2Fembers/lists"}