a custom language construction kit

Overview

Swifties

a custom language construction kit

intro

Swifties aims to provide a flexible toolkit for creating custom languages in Swift.

demo

A custom Lisp REPL is provided for demonstration purposes.

primitives

Primitives are called at compile time and may take any number (min/max are specified in the constructor) of forms as arguments and emit operations.

let pos = Pos(source: "test", line: -1, column: -1)

let p = Prim(env: env, pos: self.pos, name: "do", (0, -1), { 
pos, args in
    for a in args { try a.emit() }
})

env.openScope().bind(pos: pos, id: "do", env.coreLib!.primType, p)

functions

Functions may take any number of arguments and return any number of results; pos indicates the call site; evaluation resumes from the returned Pc.

let pos = Pos(source: "test", line: -1, column: -1)

let f = Func(env: env, pos: pos, name: "foo", args: [], rets: [env.coreLib!.intType], {
pos, self, ret in
    env.push(env.coreLib!.intType, 42)
    return ret
})

env.openScope().bind(pos: pos, id: "foo", env.coreLib!.funcType, f)

Functions may alternatively be instantiated with Form-bodies, which emits operations behind the scenes and generates a function containing the code required to evaluate them.

let f = Func(env: env, pos: pos, name: "foo", args: [], rets: [env.coreLib!.intType])
try f.compileBody(LiteralForm(env: env, pos: pos, env.coreLib!.intType, 42))

multimethods

Multimethods are sets of functions sharing the same name sorted from most specific to least that delegate to the most specific applicable function when called.

let m = Multi(env: env, pos: pos, name: "foo")
f.addFunc(f)

types

Two levels of types are used, ÀnyType, and it's direct parameterized subclass Type<T> from which all other types inherit.

  • Any - Any kind of value
  • Bool - Boolean values
  • Char - Character values
  • Cont - Continuations as values
  • Form - Forms as values
  • Func - Functions as values
  • Id - Quoted identifiers
  • Int - Integer values
  • Iter - Iterators
  • Macro - Macros as values
  • Meta - Types as values
  • Multi - Multimethods as values
  • Pair - Pairs of values
  • Prim - Primitives as values
  • Register - Register references as values
  • Seq - Iterable values
  • Stack - Stack values
  • String - String values
  • Target - Callable values

parsing

Parser may be used to simplify the process of turning code into forms.

let pos = Pos("test", line: -1, column: -1)
let env = Env()
try env.initCoreLib(pos: pos)

let parser = Parser(env: env, source: "test",
                    prefix: [spaceReader, intReader],
                    suffix: [])
                    
try parser.slurp("1 2 3")
for f in parser.forms { try f.emit() }
env.emit(STOP)
try env.eval(0)

XCTAssertEqual(Slot(env.coreLib!.intType, 3), env.pop(pos: pos)) 
XCTAssertEqual(Slot(env.coreLib!.intType, 2), env.pop(pos: pos)) 
XCTAssertEqual(Slot(env.coreLib!.intType, 1), env.pop(pos: pos)) 

readers

Readers specialize in parsing a specific kind of form.

  • Call - Reads call forms
  • Char - Reads character literals
  • Id - Reads identifiers
  • Int - Reads integer literals
  • Pair - Reads pair literals
  • Quote - Reads quoted forms
  • Space - Skips whitespace
  • Splice - Reads spliced expressions
  • Stack - Reads stack literals
  • String - Reads string literals

It's trivial to extend the framework with custom readers. Just make sure to return nil if you can't find what you're looking for, since each reader is tried in sequence for every new position.

func intReader(_ p: Parser) throws -> Form? {
    let fpos = p.pos
    var v = 0
        
    while let c = p.getc() {
        if !c.isNumber {
            p.ungetc(c)
            break
        }
            
        v *= 10
        v += c.hexDigitValue!
        p.nextColumn()
    }
        
    return (p.pos == fpos) ? nil : LiteralForm(env: p.env, pos: p.pos, p.env.coreLib!.intType, v)
}

forms

Code is parsed into forms, which is what primitives and macros operate on.

  • Call - Emits code to call specified target with args
  • Do - Emits args in sequence
  • Id - Emits the value of specified binding and calls it if possible
  • Literal - Emits code to push specified value
  • Pair - Emits code to push specified pair
  • Quote - Emits code to push quoted form
  • Splice - Emits result of evaluating form if quoted depth is 1
  • Stack - Emits code to push a stack with specified items

operations

Forms emit operations, which are the basic building blocks that are eventually evaluated in sequence to get the desired result.

  • Bench - Repeats body specified number of times and pushes elapsed time in milliseconds
  • Branch - Branches conditionally
  • Call - Calls specified value
  • Drop - Drops specified number of items from stack
  • For - Repeats code for each value in sequence on top of stack
  • Goto - Resumes evaluation from specified Pc
  • Load - Loads value from specified register
  • Push - Pushes specified value on stack
  • PushDown - Pushes top of stack onto next item
  • Quote - Quotes and pushes specified form
  • Recall - Restarts current function without pushing frame
  • Reset - Clears stack
  • Restore - Restores continuation
  • Return - Pops frame from call stack and resumes evaluation from it's return pc
  • Splat - Replaces top of stack (which has to be iterable) with it's items
  • Stop - Stops evaluation without error
  • Store - Stores value in specified register
  • Suspend - Pushes continuation
  • Zip - Replaces top two stack items with pair

Operations may be manually emitted at any point using Env.emit(Op).

let pos = Pos("test", line: -1, column: -1)
let env = Env()
try env.initCoreLib(pos: pos)
let v = Slot(env.coreLib!.intType, 42)
env.emit(Push(pc: env.pc, v))
env.emit(STOP)
try env.eval(0)
XCTAssertEqual(v, env.pop(pos: pos))

todo

  • add filter like map
    • add odd?/even? to math
  • add lambdas
    • extract subclass from Func
    • add type
    • trap stack target in call form
      • push lambda
      • ([x y z] [] ...)
  • finish macros
  • add support for \n & \t to char/stringReader
  • add string interpolation
    • swift syntax
  • add unsafe prim
    • add Env.safetyLevel = 0
    • add Unsafe op
      • copy Bench
      • dec/defer inc safetyLevel
    • add Env.unsafe { safetyLevel > 0 }
    • skip Func.IsApplicable if env.unsafe
    • skip result check in Frame.restore if env.unsafe
  • add return prim
    • emit args & Return
  • make suggestions based on edit distance for missing ids
    • recursive like find
You might also like...
Launch App in selected language, or set as Default language

app lang switcher alfred workflow Launch App in selected language, or set as Default language. Credits: This is a swift clone of AlfredWorkflow-App-La

Elegant SVG animation kit for swift
Elegant SVG animation kit for swift

Elephant This is SVG animation presentation kit for iOS. Example You can run example app. Please open Example-iOS/Elephant-iOS.xcworkspace! Usage You

VEditorKit - Lightweight and Powerful Editor Kit built on Texture(AsyncDisplayKit)
VEditorKit - Lightweight and Powerful Editor Kit built on Texture(AsyncDisplayKit)

VEditorKit provides the most core functionality needed for the editor. Unfortunately, When combined words are entered then UITextView selectedRange will changed and typingAttribute will cleared. So, In combined words case, Users can't continue typing the style they want.

iOS SwiftUI starter kit based on Sketch Elements.
iOS SwiftUI starter kit based on Sketch Elements.

iOS Sketch Elements iOS Sketch Elements is iOS SwiftUI starter kit based on Sketch Elements. More information and screenshots here. Roadmap General Na

App Design Kit is a collection of beautifully designed, ready-to-use, iOS app template screens.
App Design Kit is a collection of beautifully designed, ready-to-use, iOS app template screens.

App Design Kit is a collection of beautifully designed, ready-to-use, iOS app template screens. This well-structured, Swift coded, UI Kit bundle helps you to create your own application much faster than starting from scratch, using a simple design file.

A Swift Formatter Kit
A Swift Formatter Kit

Format A Swift formatter kit. Simple formatting syntax for decimal numbers, currency, mass, addresses, ordinal numbers and hexadecimal colors. Usage I

EU Digital COVID Certificate Kit for the Apple Platform  (unofficial)
EU Digital COVID Certificate Kit for the Apple Platform  (unofficial)

EU Digital COVID Certificate Kit A Swift Package to decode, verify and validate EU Digital COVID Certificates for iOS, tvOS, watchOS and macOS Disclai

Applozic UI Kit in Swift
Applozic UI Kit in Swift

Official iOS Swift SDK for Chat 💬 Introduction 🌀 Applozic brings real-time engagement with chat, video, and voice to your web, mobile, and conversat

A Lightweight But Powerful Color Kit (Swift)
A Lightweight But Powerful Color Kit (Swift)

BCColor A lightweight but powerful color kit (Swift) Features Pick Colors From Image Generate Monochrome Image Support Hex Color Style Lighten / Darke

a collectionView made for Sprite Kit
a collectionView made for Sprite Kit

CollectionNode A collectionView made for Sprite Kit installation Carthage Carthage is a dependency manager that provides binary frameworks for your pr

NXDrawKit is a simple and easy but useful drawing kit for iPhone
NXDrawKit is a simple and easy but useful drawing kit for iPhone

⚠️ To use with Swift 5.0 please ensure you are using = 0.8.0 ⚠️ ⚠️ To use with Swift 4.2 please ensure you are using = 0.7.1 ⚠️ ⚠️ To use with Swift

LaiFeng IOS Live Kit,H264 and AAC Hard coding,support GPUImage Beauty, rtmp transmission,weak network lost frame,Dynamic switching rate
LaiFeng IOS Live Kit,H264 and AAC Hard coding,support GPUImage Beauty, rtmp transmission,weak network lost frame,Dynamic switching rate

LFLiveKit LFLiveKit is a opensource RTMP streaming SDK for iOS. Features Background recording Support horizontal vertical recording Support Beauty Fac

A Swift Reactive Programming Kit
A Swift Reactive Programming Kit

ReactiveKit is a lightweight Swift framework for reactive and functional reactive programming that enables you to get into the reactive world today. T

Small swift events kit

CoreEvents Small Swift events kit that provides some base types of events: FutureEvent PresentEvent PastEvent FutureEvent Simple event. Provides class

Twitter Kit is a native SDK to include Twitter content inside mobile apps.

Twitter will be discontinuing support for Twitter Kit on October 31, 2018. Read the blog post here. Twitter Kit for iOS Background Twitter Kit is a na

Swift UI Kit to present clean modal/alert
Swift UI Kit to present clean modal/alert

CleanyModal is a good way to use UI-Customised alerts with ease Features Present some kind of clean alerts (With same API as UIAlertViewController) Ad

UI Kit for the STREAMD anime app. Generic UI objects go here, nothing to do with anime

STREAMDUIKit UI Kit for the STREAMD anime app. Generic UI objects go here, nothi

FrameLayoutKit is a super fast and easy to use autolayout kit
FrameLayoutKit is a super fast and easy to use autolayout kit

FrameLayoutKit FrameLayout is a super fast and easy to use layout library for iOS and tvOS. For Objective-C version: NKFrameLayoutKit (Deprecated, not

RadarKit - The Radar Kit allowing you to locate places, trip neary by you Or it will help you to search out the people around you with the few lines of code
Owner
Andreas Nilsson
I am by nature a dealer in words, and words are the most powerful drug known to humanity.
Andreas Nilsson
Swift friendly localization and i18n with in-app language switching

Localize-Swift Localize-Swift is a simple framework that improves i18n and localization in Swift iOS apps - providing cleaner syntax and in-app langua

Roy Marmelstein 2.9k Dec 29, 2022
iOS implementation of the Catrobat language

Catty Catty, also known as Pocket Code for iOS, is an on-device visual programming system for iPhones. Catrobat is a visual programming language and s

null 74 Dec 25, 2022
Demo project of Swift language crash using Release build on iOS 14

Demo project of Swift language crash using Release build on iOS 14 Repro steps O

Daohan Chong 0 Mar 24, 2022
ParserCombinators - String Parser Construction Kit

ParserCombinators provides a set of elementary building blocks for deriving stru

Marcel Tesch 0 Jan 7, 2022
A note on the Construction of the watchOS App Notes

This document is a note on the Construction of the watchOS App "Notes" Learn about the main topics of this watchOS project In this SwiftUI tutorial, w

Daniel Beatty 0 Dec 6, 2021
Kit for building custom gauges + easy reproducible Apple's style ring gauges.

GaugeKit ##Kit for building custom gauges + easy reproducible Apple's style ring gauges. -> Example Usage Open GaugeKit.xcworkspace and change the sch

Petr Korolev 1k Dec 23, 2022
Localization of the application with ability to change language "on the fly" and support for plural form in any language.

L10n-swift is a simple framework that improves localization in swift app, providing cleaner syntax and in-app language switching. Overview ?? Features

Adrian Bobrowski 287 Dec 24, 2022
A repository for showcasing my knowledge of the Swift programming language, and continuing to learn the language.

Learning Swift (programming language) I know very little about programming in the Swift programming language. This document will go over all my knowle

Sean P. Myrick V19.1.7.2 2 Nov 8, 2022
A repository for showcasing my knowledge of the Objective-C++ programming language, and continuing to learn the language.

Learning Objective-C-Plus-Plus I hardly know anything about the Objective-C++ programming language. This document will go over all of my knowledge of

Sean P. Myrick V19.1.7.2 3 Nov 8, 2022
A repository for showcasing my knowledge of the Objective-C programming language, and continuing to learn the language.

Learning Objective-C I hardly know anything about the Objective-C programming language. This document will go over all of my knowledge of the Objectiv

Sean P. Myrick V19.1.7.2 3 Nov 8, 2022