Skip to content

Commit

Permalink
examples: Add examples I'm using to sketch out the grammar of the lan…
Browse files Browse the repository at this point in the history
…guage
  • Loading branch information
obiwac committed Jul 4, 2024
1 parent 7884dff commit ec7b8ba
Show file tree
Hide file tree
Showing 3 changed files with 219 additions and 0 deletions.
91 changes: 91 additions & 0 deletions examples/bob.fl
Original file line number Diff line number Diff line change
@@ -0,0 +1,91 @@
# This Source Form is subject to the terms of the AQUA Software License,
# v. 1.0. Copyright (c) 2024 Aymeric Wibo

## The install map maps file names to where they should be installed.
## These destination paths are prefixed by the installation prefix, which can only be set by the user.
## On most common Linux distributions, this would be '/usr' by default.
## On FreeBSD, this is '/usr/local' by default.
##
## ```fl
## install = {
## "foo": "bin/foo",
## "bar": "bin/bar",
## }
## ```
install: map<str, str>

## Function to be called when the project is run.
## The arguments passed to Bob are passed as a vector of strings to the `args` parameter.
## The return value should be the exit code of the program (i.e. 0 on success and anything else on error).
##
## ```fl
## fn run(args) {
## return Sys.exec(cmd_path, args)
## }
## ```
##
## In the above example, it is assumed that `cmd_path` is the path to an executable generated by the build step.
fn run(args: vec<str>) -> int;

## C compiler class.
extern class CC {
## Add a flag to the C compiler.
##
## ```fl
## cc.add_opt("-std=c99")
## ```
extern fn add_opt(self, option: str) -> void;

## Compile a C source file.
## Returns the path to the object file.
##
## ```fl
## object_file_path = cc.compile("main.c")
## ```
extern fn compile(self, src_path: str) -> str;
}

## Linker class.
extern class Linker {
## Create a static library ('.a') from a list of object files.
## Returns the path to the static library.
##
## ```fl
## lib_path = linker.static(["main.o", "foo.o", "bar.o"])
## ```
extern fn static(self, out_path: str) -> void;

## Create a dynamic library (aka a shared object, '.so') from a list of object files.
## The second argument is a list of other libraries to link against.
## For example, if your library necessarily depends on 'libm', you would pass '["m"]' as the second argument.
## Returns the path to the dynamic library.
##
## ```fl
## lib_path = linker.dynamic(["main.o", "foo.o", "bar.o"])
## lib_path = linker.dynamic(["main.o", "foo.o", "bar.o"], ["m"])
## ```
extern fn dynamic(self, out_path: str, other_libs: vec<str> = []) -> void;

## Create an executable from a list of object files.
## The second argument is a list of other libraries to link against.
## For example, if your library necessarily depends on 'libm', you would pass '["m"]' as the second argument.
## Returns the path to the executable.
##
## ```fl
## exe_path = linker.link(["main.o", "foo.o", "bar.o"])
## exe_path = linker.link(["main.o", "foo.o", "bar.o"], ["m"])
## ```
extern fn link(self, out_path: str, other_libs: vec<str> = []) -> void;
}

## Resource class.
extern class Res {
## Add a resource to the project.
## This essentially copies your resource to the build directory untouched.
## Returns the new path to the resource.
##
## ```
## res_path = res.add("header.h")
## ```
extern pure fn add(path: str) -> str;
}
52 changes: 52 additions & 0 deletions examples/iar_build.fl
Original file line number Diff line number Diff line change
@@ -0,0 +1,52 @@
# This Source Form is subject to the terms of the AQUA Software License,
# v. 1.0. Copyright (c) 2024 Aymeric Wibo

import std
import bob

# C compilation.

cc = CC()

cc.add_opt("-Isrc")
cc.add_opt("-fPIC")
cc.add_opt("-std=c99")
cc.add_opt("-Wall")
cc.add_opt("-Wextra")
cc.add_opt("-Werror")

lib_src = Fs.list("src/lib")
.where(fn(path) path.ends_with(".c"))

cmd_src = Fs.list("src/cmd")
.where(fn(path) path.ends_with(".c"))

src = lib_src ++ cmd_src
src.map cc.compile

# Create static & dynamic libraries and command-line frontend executable.

linker = Linker()

archive_path = linker.static(lib_src)
dyn_lib_path = linker.dynamic(lib_src)
cmd_path = linker.link(cmd_src, ["iar"])

# Add header as a resource.

header_path = Res.add("src/iar.h")

# How to run the command-line frontend?

fn run(args) {
return Sys.exec(cmd_path, args)
}

# Installation map.

install = {
cmd_path: "bin/iar",
archive_path: "lib/libiar.a",
dyn_lib_path: "lib/libiar.so",
header_path: "include/iar.h",
}
76 changes: 76 additions & 0 deletions examples/std.fl
Original file line number Diff line number Diff line change
@@ -0,0 +1,76 @@
# This Source Form is subject to the terms of the AQUA Software License,
# v. 1.0. Copyright (c) 2024 Aymeric Wibo

## The `str` class provides methods on the builtin string type.
extern class str {
## *Check* if a string ends with the given suffix.

## ```fl
## s = "Hello world!"
## assert s.ends_with("world!") == true
## assert s.ends_with("world") == false
## ```
extern pure fn ends_with(self, suffix: str) -> bool;
}

## The `vec` class provides methods on the builtin vector type.
extern class vec {
## Filter the elements of the vector based on a predicate.
## For example, a list of numbers could be filtered to only include the even ones.
##
## ```fl
## assert [1, 2, 3, 4, 5].where(fn(x) x % 2 == 0) === [2, 4]
## ```
extern pure fn where(self, filter: fn(subject) -> bool) -> vec;

## Apply a function to each element of the vector.
## For example, a list of numbers could be squared.
##
## ```fl
## assert [1, 2, 3, 4, 5].map(fn(x) x ** 2) === [1, 4, 9, 16, 25]
## ```
extern pure fn map(self, action: fn(subject)) -> vec;

## Concatenate two vectors.
##
## ```fl
## assert [4, 2, 0] ++ [6, 9] === [4, 2, 0, 6, 9]
## ```
extern pure fn ++(self, other: vec) -> vec;

## Check if two vectors are equal.
##
## ```fl
## assert ([4, 2, 0] === [4, 2, 0]) == true
## assert ([4, 2, 0] === [4, 2, 1]) == false
## ```
extern pure fn ===(self, other: vec) -> bool;
}

## The `Fs` class provides methods to interact with the filesystem.
extern class Fs {
## List the files in a directory.
## If given a depth greater or equal to 0, it will list the files recursively up to the given depth.
## A depth of -1 will list all files at an infinite depth.
## The order of the entries is not guaranteed.
##
## ```fl
## assert Fs.list(".") === [] # TODO
## assert Fs.list(".", 0) === [] # TODO
## assert Fs.list(".", 1) === [] # TODO
## ```
extern pure fn list(path: str, depth: int = -1) -> vec<str>;
}

## The `Sys` class provides methods to interact with the system.
extern class Sys {
## Execute a command with arguments.
## The command is executed in a new process.
## The return value is the exit code of the command.
## Capturing the standard output of the command is unsupported at the moment :(
##
## ```fl
## assert Sys.exec("echo", ["Hello", "world!"]) == 0
## ```
extern pure fn exec(cmd: str, args: vec<str>) -> int;
}

0 comments on commit ec7b8ba

Please sign in to comment.