6 releases
| 0.3.0 | Jul 19, 2022 |
|---|---|
| 0.2.0 | Mar 18, 2022 |
| 0.1.3 | Sep 24, 2021 |
| 0.1.2 | Jul 18, 2021 |
| 0.1.1 | Jun 2, 2021 |
#255 in Programming languages
27 downloads per month
90KB
2.5K
SLoC
Parser for Leap language.
Links:
- Command line tool - formatting and verification.
Leap language.
Leap is a light, simple language for describing data structures.
Supported data types:
str- utf-8 stringint- 64-bit integer numberfloat- 64-bit floating point numberbool- boolean typelist- array of valuesstruct- user defined type with fieldsenum- user defined type with multiple variants
Naming
All user defined names use kebab case (all letters are lower case, separated with -), eg.: user-auth, article-title, some-long-long-long-name:
- name should start with a letter and can contain numbers
- words in the name are separated with a single
-
List
List defines array of values and accept single type argument for the type of elements:
list[int]- list of integerslist[user]- list ofuserstructslist[list[string]]- list of lists of strings
Struct
Struct is a user defined type, can have zero or more fields, and can have type arguments for generict values.
Example:
.struct user
name: str
age: int
address: str
tags: list[str]
active: bool
here user.name is string, and user.tags is list of strings
Empty struct with no fields:
.struct none
Struct with type argument:
.struct some[t]
value: t
here t is a type argument, and if it will be applied as str, value will become str
Enum
Enum is a user defined type, which describes which variants it can be, only structs can be variants of enum, enum can have type arguments.
Example:
.enum response
user
none
here response can be either user or none struct
Variants can be named:
.enum account
admin: user
customer: user
here variant names allow to avoid name conflict, as both variants admin and customer use same type user.
Enum with type argument:
.enum option[t]
some[t]
none
here t is a type argument, and if it will applied as int, some[t] variant will become some[int]
Type arguments
Types can have type arguments for generic values. If there is multiple type arguments, they separated with spaces:
.struct some-struct[a b c]
value-a: a
value-b: b
value-c: c
value-d: other-struct[a b list[c]]
value-e: some[int]
here a, b, c is type arguments, which should be applied in order to use type, for example some-struct[int int str], in this case value-a will have int type, and value-d will have other-struct[int int list[str]] type. value-e have type some[int], which is some[t] with t applied as int.
Comments
Comments start with /-- and can be placed on separate line, or at the end of the line:
/-- some comment about page struct
.struct page[t]
items: list[t] /-- other comment about items of page
/-- comment about page additional info
total-count: int
Example
Lets model types which can be used for REST API of blog engine:
/-- general types
.struct none
.struct some[t]
value: t
.enum option[t]
none
some[t]
.enum result[t e]
ok: some[t]
err: some[e]
/-- api types
.struct page[t]
value: t
total-count: option[int]
.struct user
id: int
name: str
email: str
.struct article
id: int
author: user
title: str
text: str
tags: list[str]
here for our api:
- for every request api returns
result[t str],tfor correct response orstrfor error (string with error message) GET /users/7will returnresult[user str], which allows to get info about user by id on success or error messageGET /articleswill returnresult[page[article] str], which allows to get paged list of articles on success or error messagepage.total-countis optional, iftotal-countis unknown it will be equal tonone, otherwisesome[int]
Example usage
Cargo.toml
[dependencies]
leap-lang = "0.2"
main.rs
use leap_lang::parser::parser::Parser;
fn main() {
let types = Parser::parse("
.enum enum1
.struct struct1
.struct struct2
v1: int
").unwrap();
for t in types {
println!("name: {}", t.name());
}
// output:
//
// name: enum1
// name: struct1
// name: struct2
}