A programming language for generating code for multiple platforms

Related tags

Tools Zolang
Overview

Zolang ZolangTemplatesZolang IDE

Zolang Logo

Swift Platforms MIT

Table of Contents

What is it?

Documentation

Roadmap

Why Zolang?

Name

License

Zolang

A lightweight frontend for virtually any general purpose programming language.

What is it?

Zolang is a programming language with capabilities that make it transpilable to virtually any other programming language.

Zolang does this by offloading code generation to its users through Stencil (template language) specification files.

Theoretically though, these (.stencil) specification files could make Zolang output any kind of text. Making the language a very useful code generation tool and a decent lightweight alternative to many cross-platform frameworks.

What Zolang is Not

Zolang is not a general purpose programming language and probably won't have support for standard library functionalities in the forseeable future. This is because Zolang uses a templating language for compilation, which is not the expected usage of such a language, and becomes slow quite quickly, limiting the amount of code feasable for Zolang development.

Documentation

Installation

MacOS

curl -LO https://github.com/Zolang/Zolang/releases/download/0.1.18/zolang
mv zolang /usr/local/bin/
chmod +x /usr/local/bin/zolang

Linux & Mac (Build From Source)

At the time of writing there is a bug in Swift on Linux that prevents me from providing working build for Linux so if you're running on Linux you will (for now) have to have Swift installed (Download Swift) and simply build from source.

git clone https://github.com/Zolang/Zolang
cd Zolang
swift build -c release
cd .build/release
cp -f Zolang /usr/local/bin/zolang

Verify installation

zolang

Getting Started

Setting up development environment

Zolang is best with Visual Studio Code using the zolang-ide extension

Initializing Project

If you don't have an existing project start by creating a project folder and navigate to it

mkdir  MyZolangProject
cd MyZolangProject

Then initialize the project

zolang init

This will create a zolang.json file that will be used to specify build settings for your Zolang and setup the project's file structure.

Example

The Config File

A typical zolang.json project file compiling to Swift, Kotlin and Python would look something like this:

{
  "buildSettings": [
    {
      "sourcePath": "./.zolang/src",
      "stencilPath": "./.zolang/templates/swift",
      "buildPath": "./.zolang/build/swift",
      "fileExtension": "swift",
      "separators": {
        "CodeBlock": "\n"
      },
      "flags": [
        "swift"
      ] 
    },
    {
      "sourcePath": "./.zolang/src",
      "stencilPath": "./.zolang/templates/kotlin",
      "buildPath": "./.zolang/build/kotlin",
      "fileExtension": "kt",
      "separators": {
        "CodeBlock": "\n"
      },
      "flags": [
        "kotlin"
      ]
    },
    {
      "sourcePath": "./.zolang/src/",
      "stencilPath": "./.zolang/templates/python2.7",
      "buildPath": "./.zolang/build/python2.7",
      "fileExtension": "py",
      "separators": {
        "CodeBlock": "\n"
      },
      "flags": [
        "python2.7"
      ]
    }
  ]
}

Notice the ./.zolang/templates/{LANGUAGE} This is the location of the .stencil files that customize the actual code generation process. The Zolang organization has a repo of supported languages. But zolang init only fetches the three (Swift, Kotlin and Python).

./zolang/src is where all the Zolang code is stored.

flags are compile time constants that can be used in only statements see docs

😇 P.S. It only took around an hour to add the templates needed to be able to compile Zolang to both Kotlin and Swift! So you shouldn't restrain yourself from using Zolang if your favorite language is not yet supported. Just add it and continue hacking.

Your First Model Description

We could create a file ./zolang/src/Person.zolang

describe Company {
  name as text
  revenue as number

  employeeNames as list of text default []
}

Building

Just ...

zolang build

... and enjoy checking out the readable code generated to ./zolang/build/swift/Person.swift and ./zolang/build/kotlin/Person.kt

Hot Reloading

Zolang supports hot reloading or live compilation through the watch action

zolang watch

This action will observe changes to Zolang source files with paths specified in zolang.json and rebuild.

Zolang hot-reloading

Language Overview

Types

Zolang has five primitive types

  • boolean
  • text
  • number
  • list
  • dictionary
boolean

Values are either true or false

See section below on operators for further information

text

Defined within double quotes

"a piece of text"

You can format a piece of text using ${...}

"this is a string with an embedded variable: ${someVar}"

The limitation when it comes to text in Zolang is that the language doesn't care for characters that need to be escaped.

The text: "this is a text \n" would remain unchanged when compiling to other languages which might become a problem if \n is handled differently in the other languages the Zolang code is being compiled to. Thankfully languages seem to handle character escaping in a somewhat similar fassion so most of the time this does not make a difference.

number

Zolang currently only has one type to represent numbers.

Numbers work just as you would expect:

let num1 as number be 0.12345

let num2 as number be 5
list

The same goes for lists. They represent ... you guessed it, lists of data; and are declared by using the list keyword followed by a of keyword and finally the type of the element you want to represent.

List literals are defined with a comma separated sequence of expressions wrapped inside enclosing brackets [...]

let myList as list of text be [ "1", "2", "3" ]
dictionary

Dictionaries might be a bit different to the key-value types you're used but fear not they're just as easy to understand.

In Zolang dictionaries only have one available Key type, text, so their usage becomes similar to lists:

let myDict as dictionary of number be { "num1": 5, "num2": 7.5 }

This is to make sure all pure Zolang models are easily serializable to JSON so that later on templates in ZolangTemplates will be able to autogenerate serialization methods for all models.

Operators

Prefix Operators

There is only one supported prefix operator in Zolang

not and ! both meaning the same thing and are meant to be used as negation for boolean types

Infix Operators

Infix operators in Zolang:

  • or, ||: boolean or
  • and, &&: boolean and
  • <: less-than
  • >: greater-than
  • <=: lesser-than-or-equal
  • >=: greater-than-or-equal
  • equals, ==: equality
  • plus, +: addition
  • minus, -: subtraction
  • multiplied by, times, *: multiplication
  • divided by, over, /: division
  • modulus, %: modulus

NOTE! Watch out for precedence. Zolang offloads precedence handling to the languages being compiled to. With types that are of number type this is seldom an issue but as Zolang doesn't currently support type checking, any operator can be used on any type, so beware.

Comments

Zolang currently only supports single line comments prefixed by #. Currently, comments are ignored in the build phase and can only be used to document Zolang code.

# This is a comment

Describing a Model

describe Person {
  name as text 
  street as text
  number as number
  friendNames as list of text
}

Now like you can create a Person by calling:

let john as Person be Person("John", "Wall Street", 15, [ "Alice", "Bob" ])
Access Control

It can be handy to be able to specify some ground rules as to what code can access what properties.

If we look at Person example from above we might want to limit access to his address to be only accessable from within the Person's description.

This can be done by using the private access limitation specifier

Currently supported access limitation specifiers are

  • private

If nothing is specified the property/function will be declared public

private street as text
private number as number
Default Values

Properties can also have default values

private street as text default "John"
Static

Zolang allows static declaration of properties/functions:

static species as text default "Homo Sapiens"

This can then be accessed by calling:

Person.species

Variable Declaration

let person as Person be Person("John Doe", "John's Street", 8, [ "Todd" ])

Mutation

make person.name be "Jane Doe"

Functions

Functions in Zolang can be declared in a model description, in Person, the model we described above we could define a function address which would combine street and number as so:

describe Person {
  name as text 
  street as text
  number as number
  friendNames as list of text
  
  address return text from () {
    return "${street} ${number}"
  }
}
Invoking Functions
person.speak("My address is ${person.address()}")

Arithmetic

Lets say we wanted to calculate something like 1 + 2 + (3 * 4) / 5

In Zolang this would be written in various ways:

1 + 2 (3 * 4) / 5
1 plus 2 plus (3 times 4) over 5
1 plus 2 plus (3 times 4) divided by 5

Looping through Lists

let i as number be 1

while (i < person.friendNames.count) {
  make i be i plus 1
}

Metaprogramming

In Zolang there are two features designed for metaprogramming purposes, raw and only

raw
raw {'Any text here'}

This will tell the compiler to skip the code generation process for "Any text here" and forward it as is to the compiler's output

only

only "<flag1>", "<flag2>",... { <code> }

Using only we can tell the compiler to ignore code for buildSettings not included in a comma separated list of flags (flags are specified in ./zolang.json under "flags" in each buildSetting)

only "python2.7", "swift" {
  print("text")
}
Putting it all Together

Using these two features (raw & only) we could create a facade for logging to the console:

describe Sys {
  static log return from (txt as text) {
    only "python2.7", "swift" {
      raw {'print(txt)'}
    }
    only "kotlin" {
      raw {'println(txt)'}
    }
  }
}

Sys.log("Hello World!")

Roadmap / Upcoming Features

  • Faster compilation
  • Fetch ZolangTemplates from the Zolang CLI
  • Update Zolang from the Zolang CLI
  • Type checking
  • For loop
  • Function mutation

Why Zolang?

Zolang doesn't try to be a general purpose programming language, it is limited in features and is yet to have a standard library, so why use Zolang instead of other programming languages?

... well, it's transpilable to multiple languages including Kotlin, Swift and Python and there are few limits to how many languages can be supported, to give you the idea of how soon your favorite language will be supported (if not already) adding support for all the three aforementioned languages took about an hour.

This means that Zolang is very good for implementing basic logic in your app with a single source of truth, generating code needed for virtually all platforms your app is running on.

A User Story: The Story Behind Zolang

The idea for Zolang came from within a fast moving startup. It was moving fast in the sense that the tech stack was rapidly changing every now and then, the product had projects in 4 languages, Swift, TypeScript, JavaScript and Ruby. All of which had duplications in definitions of models.

So every time the tech stack changed drastically, changes had to be made in many of the (if not all four) implementations. So we wanted a language where we could write the model layer of our application with a single source of truth, generating code for all of our programming languages.

Name

I'm a Star Wars fan and in the Star Wars world Zolan is the home planet of a species called clawdites, who are known for their ability to transform their appearance to look like virtually any other creature.

As the language aims to be transpilable to virtually any other programming language the clawdites came quickly to mind. Sadly the species doesn't have a catchy name, so I found myself falling back to their planet Zolan. And since this is a language and lang is often used as an abbreviation for language the "g" was soon to follow.

Remember this guy from "Attack of the Clones":

Clawdite

That is a clawdite, my inspiration for the name and logo.

License

MIT License

Copyright (c) 2018 Thorvaldur Runarsson

Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:

The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.

THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.

Comments
  • Division Infix operators needed

    Division Infix operators needed

    All the operators have support for their mathematical symbols, except division. Add support for / as a division operator for consistency sake.

    This can be a good "newcomer" issue!

    Love this code base, and would definitely love to help.. when I find the time 🙄

    opened by magtastic 2
  • Change README setup

    Change README setup

    This is more a suggestion, rather than hoping to be merged.

    List of things I look for in a Github readme (in this order):

    1. What is it? (one sentence please.)
    2. How do I get it working on my machine.
    3. How do I use it.
    4. Other stuff
    opened by magtastic 0
  • Add built in memory support for top languages

    Add built in memory support for top languages

    Languages such as

    MVP Kotlin, Swift, Python, JavaScript, ...

    Later Ruby?, Haxe?

    should all be supported from within the app and shouldn't need templates.

    We should refactor backend and config file setup to support built in language transpilation as well as template file support.

    opened by valdirunars 0
  • GraphQL integration consideration

    GraphQL integration consideration

    Hi, thanks for creating this. Very interesting project. I'm interested in looking at cross-platform code generators that can work with many languages that are hackable and I can contribute to. So far the best ones I've found are implemented with GraphQL (see https://github.com/prisma/prisma-binding or https://github.com/aws-amplify/amplify-js with AppSync) or a proprietary CLI within a framework (like Angular Schematics - https://www.npmjs.com/package/@angular-devkit/schematics).

    While the above projects are much larger in scope, I think GraphQL as a DSL is a very standardized option with rich community support and a huge ecosystem. It also gives the flexibility to generate full-fledged API's integrated with GraphQL. So, rather than just generating classes, it would be possible to generate entire queries, mutations, and subscriptions on top of an API layer that can be packaged to the frontend.

    On the frontend, there is another challenge that Zolang can solve: the generators on the backend are usually very different from the generators on the frontend. However, with Zolang, you can just create a separate "generator mapping template" file like shown in your examples and create model classes for the frontend as well with service-level integrations to the backend code. What do you think?

    opened by selipso 2
  • Create documentation about creating Zolang templates

    Create documentation about creating Zolang templates

    Different templates receive different types of contexts. We should have API documentation for the contexts either in this repo or ZolangTemplates

    You can see all the standard names of stencil files in ZolangTemplates

    NOTE: It's very good to see how the contexts are created.

    In this repo under Sources -> ZolangCore -> Frontend -> Models -> Nodes

    You can see the objects that generate these contexts that are passed on to the template engine.

    Alternatively you could search the repo for getContext function declarations to investicate how they are created.

    enhancement help wanted good first issue 
    opened by valdirunars 0
  • Fix tests on Linux

    Fix tests on Linux

    Currently tests are hardcoded as empty

    XCTMain([])
    

    We want this to import ZolangTests and properly Test project so that running swift test on linux actually works

    See this reference on how to implement

    help wanted good first issue 
    opened by valdirunars 0
Releases(0.1.19)
Owner
Zolang
The Zolang programming language organization
Zolang
Objective-c code Apple style documentation set generator.

About appledoc IMPORTANT NOTICE: collaborators needed appledoc is command line tool that helps Objective-C developers generate Apple-like source code

tomaz 4.2k Dec 20, 2022
Laurine - Localization code generator written in Swift. Sweet!

Author's note: Thanks everyone for making Laurine the TOP trending Swift repository in the world - this is amazing and very heart-warming! But this is

Jiri Trecak 1.3k Dec 28, 2022
An Xcode plug-in to format your code using SwiftLint.

SwiftLintXcode An Xcode plug-in to format your code using SwiftLint. Runs swiftlint autocorrect --path CURRENT_FILE before *.swift file is saved. IMPO

Yuya Tanaka 348 Sep 18, 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
Awesome-swift-platforms - A curated list of Swift on different platforms

Embedded Swift A curated list of Swift on different platforms. Nintendo Switch S

Devran Cosmo Uenal 4 Feb 6, 2022
🚀 Create XCFrameworks with ease! A Command Line Tool to create XCFramework for multiple platforms at one shot! The better way to deal with XCFrameworks for iOS, Mac Catalyst, tvOS, macOS, and watchOS.

Surmagic ?? Create XCFramework with ease! A Command Line Tool to create XCFramework for multiple platforms at one shot! The better way to deal with XC

Muhammed Gurhan Yerlikaya 260 Dec 28, 2022
Server Driven UI can enable faster iterations and allowing apps to instantly update on multiple platforms.

Pets App Server Driven UI can enable faster iterations and allowing apps to instantly update on multiple platforms Steps to run Pets-Web: Download or

Metin Atalay 0 Jun 11, 2022
Command line tool for exporting resources and generating code from your Figma files

Fugen Fugen is a command line tool for exporting resources and generating code from your Figma files. Currently, Fugen supports the following entities

Almaz Ibragimov 69 Dec 17, 2022
JXA and swift code that can perform some macOS situational awareness without generating TCC prompts.

Spotlight Enumeration Kit Repo of Swift and JXA projects to leverage macOS Spotlight db data for the following: TCC folder permissions (TCC-Checker.js

Cedric Owens 27 Dec 5, 2022
Scaffold is a tool for generating code from Stencil templates, similar to rails gen.

?? Scaffold Scaffold is a tool for generating code from Stencil templates, similar to rails gen. It happens to be written in Swift, but it can output

Joshua Kaplan 33 Apr 5, 2022
Explanations and samples about the Swift programming language

About Swift Contents Explanations and samples about: Swift Programming Language Swift Standard Library Target audience Developers familiar with object

Nicola Lancellotti - About 74 Dec 29, 2022
Emacs support for Apple's Swift programming language.

swift-mode Major-mode for Apple's Swift programming language. Installation Install swift-mode package from MELPA. To install without MELPA, download l

null 347 Dec 17, 2022
The Package Manager for the Swift Programming Language

Swift Package Manager Project The Swift Package Manager is a tool for managing distribution of source code, aimed at making it easy to share your code

Apple 9.1k Dec 29, 2022
Tiny http server engine written in Swift programming language.

What is Swifter? Tiny http server engine written in Swift programming language. Branches * stable - lands on CocoaPods and others. Supports the latest

null 3.6k Jan 3, 2023
Tiny http server engine written in Swift programming language.

What is Swifter? Tiny http server engine written in Swift programming language. Branches * stable - lands on CocoaPods and others. Supports the latest

null 3.6k Dec 31, 2022
RSNetworking is a networking library written entirly for the Swift programming language.

RSNetworking is a networking library written entirly for the Swift programming language.

null 18 Feb 25, 2018
macOS GUI Library for the Nim Programming Language

NimCocoa NimCocoa is an experimental implementation of a Native GUI for the Nim programming language running on macOS. Rather than rely on low level c

null 32 Dec 8, 2022
The Package Manager for the Swift Programming Language

Swift Package Manager Project The Swift Package Manager is a tool for managing distribution of source code, aimed at making it easy to share your code

Apple 9.1k Jan 5, 2023
Numerals is a package containing additional numeric types for the Swift programming language.

swift-numerals Numerals is a package containing additional numeric types for the Swift programming language. Contents The package currently provides t

Alexandre H. Saad 0 Jul 28, 2022