Skip to content

Tiny v0.3.0 - Arrow Functions, Structural Types, Multipart HTTP, SQLite, and LSP Rewrite

Latest

Choose a tag to compare

@confh confh released this 04 Jul 20:50

This release adds arrow functions, hex/binary/octal number literals, inline structural type hints, interface extends, multipart HTTP file uploads, native SQLite and crypto modules, native file dialogs, and a major rewrite of the Language Server for compiler-backed diagnostics and semantic analysis.

Language Changes

  • Arrow Functions: Added => expression syntax for concise function expressions. Supports single and multi-parameter forms, typed parameters, and nested returns.
    const double = x => x * 2
    const add = (a: number, b: number) => a + b
  • Hex, Binary, and Octal Number Literals: Number literals now support 0xFF, 0b1010, and 0o77 radix formats. Underscores are allowed for readability.
  • Inline Structural Type Hints: Function parameters and return types can use inline structural types directly instead of requiring named interfaces.
    fn process(input: { name: string, age: number }): { ok: bool } {
        return { ok: true }
    }
  • Interface Extends: Interfaces can extend other interfaces. The compiler checks that extending interfaces satisfy their base requirements.
    interface Base { id: number }
    interface User extends Base { name: string }
  • InstanceValue Representation: Class instances are now stored as proper InstanceValue objects with named fields, const tracking, and private access control, replacing the previous __class object pattern. This affects typeof results and runtime type checks.
  • Spread Arguments in Method Calls: MethodCallInfo and PrintInfo now carry SpreadArgs metadata, enabling spread argument tracking through the bytecode pipeline.

Standard Library Changes

  • HTTP Multipart Uploads: Added multipart request body support for http.post, http.put, http.patch, and http.request. Pass { multipart: true, form: {...}, files: [...] } to send multipart/form-data requests.
    const res = http.post("https://example.com/upload", {
        multipart: true,
        form: { username: "tiny" },
        files: [{ field: "file", path: "./photo.png" }]
    })
  • SQLite Module: Added sqlite standard library module for embedded SQL database access.
  • Crypto Module: Added crypto standard library module.
  • fs.readBytes: Reads a file and returns a buffer value instead of a string.
  • fs.isDir / fs.isFile: Check whether a path is a directory or regular file.
  • time.parseUnix: Parses an RFC3339 timestamp string and returns a Unix timestamp in seconds, milliseconds, or nanoseconds.
  • time.TimeUnit Enum: Added Seconds, Milliseconds, Nanoseconds enum for use with parseUnix.
  • validate.interfaceOf / validate.isInterface: Runtime interface validation helpers that check whether a value satisfies a named interface.
  • ui.openFileDialog / ui.saveFileDialog / ui.selectFolderDialog: Native OS file and folder dialogs via zenity.
    const path = ui.openFileDialog("Select a file", "*.tiny")
    if path != null {
        const content = fs.readFile(path)
    }
  • Generated Type Hints: Standard library type hints are now generated from .tiny stub files via cmd/gen_hints, ensuring stub definitions stay in sync with runtime metadata.

Runtime / VM Changes

  • Child VM Control: Added runtime.VM.stop() to halt a running child VM, runtime.VM.functionExists(name) to check for a function, and runtime.VM.listFunctions() to list all exported functions.
  • Host Function Receiver Support: HostFunctionValue now carries an optional receiver, enabling method-style calls across VM boundaries.
  • Cross-VM Function Wrapping: Functions passed between VMs are now wrapped as HostFunctionValue with proper error recovery and stack cleanup via discardInterruptedCall.
  • VM Stopped/Active Tracking: VMs track stopped and active state using atomics for safe concurrent access.
  • Direct Bytecode Execution: tiny <file.tbc> now runs bytecode files directly without requiring tiny run.
  • InstanceValue Cloning: Deep-clones class instances across VM boundaries, preserving const fields, private fields, and private method tracking.

CLI Changes

  • Formatter Command: Added tiny fmt <file.tiny> to format Tiny source files in place using the built-in document formatter.

LSP Changes

The Language Server received a major rewrite this cycle. The key changes are architectural rather than incremental.

  • Compiler-Backed Diagnostics: Hover, completion, and definition features now use a CompileDiagnostic path that runs the real compiler's semantic analysis. Undefined variables, duplicate declarations, argument count mismatches, and missing return statements are reported as LSP diagnostics.
  • Semantic Model V2: Added SemanticModel with query methods: MemberType(ownerType, member) resolves member types on classes, interfaces, and built-in types; GetFunctionSignature(name) returns parameter and return type info; GetClass(name) and GetInterface(name) retrieve type definitions.
  • Source Ranges on AST Nodes: SourcePosition and SourceRange types are now attached to Param, ObjectField, ImportStmt, FunctionStmt, InterfaceStmt, PropertyExpr, IdentExpr, ObjectExpr, and TypeHint. The parser populates these during parsing.
  • Go-to-Definition for this.field: Jump-to-definition now works for class field access via this, resolving to the field declaration in the class body.
  • Go-to-Definition for Structural and Interface Fields: Definition resolution navigates to field declarations in inline structural types and named interfaces.
  • Virtual Stdlib Documents: LSP serves tiny-stdlib://module.tiny virtual documents for std library stubs. The VS Code extension registers a tiny-stdlib URI scheme provider so editors can open std source without writing stub files to disk.
  • Object Literal Completions for Union Types: Object literal completions now work inside union type parameters from std imports (e.g., ui.new({}) offers debug, hidden, frameless from WebViewOptions).
  • Multiline Method Chain Completions: Completion and hover now handle multi-line method chains like http.server(8080)\n .get("/", handler), resolving through empty lines between chained calls.
  • Scope Leak Prevention: Function parameters no longer leak into the outer scope for hover, completion, and go-to-definition when the cursor is outside the function body.
  • Field Type Inference Fix: Class fields typed as any without an initializer now correctly resolve to any instead of falling through to null.

Examples

  • SQLite (examples/17-sqlite): New example demonstrating the sqlite standard library module. Creates a database, inserts rows with parameterized queries, queries data, updates records, and closes the connection.
  • Python-to-Tiny Compiler (examples/py_tiny_compiler): A proof-of-concept compiler written entirely in Tiny that lexes, parses, and compiles a subset of Python into Tiny bytecode, then executes it in a nested VM.

Installation and Downloads

To install Tiny, download the compiler binary for your specific operating system:

  • Windows: Download tiny_windows_amd64.exe
  • Linux: Download tiny_linux_amd64 for amd64 or tiny_linux_arm64 for arm64
  • macOS (Apple Silicon): Download tiny_darwin_arm64

Note: The tiny_runtime_* assets listed in the releases page are managed automatically by the compiler during the pack and dist commands. You do not need to download them manually.