mirror of
https://github.com/Dummi26/mers.git
synced 2026-01-26 10:47:04 +01:00
moved examples to own directory
This commit is contained in:
28
examples/amogus.mers
Normal file
28
examples/amogus.mers
Normal file
File diff suppressed because one or more lines are too long
19
examples/custom_type.mers
Executable file
19
examples/custom_type.mers
Executable file
@@ -0,0 +1,19 @@
|
||||
// linked list
|
||||
type elem [int []/elem]
|
||||
|
||||
fn print_linked_list(start elem) {
|
||||
loop {
|
||||
println(start.0.to_string())
|
||||
elem = start.1
|
||||
switch! elem {
|
||||
[] {
|
||||
println("[END]")
|
||||
true // break
|
||||
}
|
||||
elem start = elem // continue
|
||||
}
|
||||
}
|
||||
[]
|
||||
}
|
||||
|
||||
[1 [2 [3 [5 [7 []]]]]].print_linked_list()
|
||||
15
examples/get_ref.mers
Normal file
15
examples/get_ref.mers
Normal file
@@ -0,0 +1,15 @@
|
||||
list = [1 2 3 4 5 6 7 8 9 ...]
|
||||
|
||||
// second = &list.get_ref(2).assume1()
|
||||
// second.debug()
|
||||
// *second = 24
|
||||
// second.debug()
|
||||
|
||||
&list.get_ref(2).assume1() = 24
|
||||
should_not_be_changeable = &list.get(3).assume1()
|
||||
should_not_be_changeable = 24
|
||||
|
||||
if list.get(2) != [24] println("[!!] list.get(2) != 24 (was {0})".format(list.get(2).to_string()))
|
||||
if list.get(3) == [24] println("[!!] list.get(3) == 24")
|
||||
|
||||
list.debug()
|
||||
51
examples/gui.mers
Executable file
51
examples/gui.mers
Executable file
@@ -0,0 +1,51 @@
|
||||
lib mers_libs/gui
|
||||
|
||||
base = gui_init()
|
||||
column = base.gui_add(Column: [])
|
||||
|
||||
text = column.gui_add(Text: "Welcome to MERS GUI!")
|
||||
|
||||
button = column.gui_add(Button: "This is a button.")
|
||||
second_button = column.gui_add(Button: "This is a second button.")
|
||||
|
||||
text_state = -2
|
||||
second_text = column.gui_add(Text: "press the button above to remove this text!")
|
||||
|
||||
loop {
|
||||
for event gui_updates() {
|
||||
switch! event {
|
||||
ButtonPressed([int ...]) {
|
||||
e = event.noenum()
|
||||
match e {
|
||||
&e.eq(&button) println("First button pressed")
|
||||
&e.eq(&second_button) {
|
||||
// don't match on text_state because we need to change the original from inside the match statement
|
||||
state = text_state
|
||||
match state {
|
||||
// the first, third, fifth, ... time the button is pressed: remove the text
|
||||
text_state.mod(2).eq(0) {
|
||||
if text_state.eq(-2) {
|
||||
// the first time the button is pressed
|
||||
text_state = 0
|
||||
set_title("keep pressing the button!")
|
||||
}
|
||||
second_text.gui_remove()
|
||||
}
|
||||
// the 2nd, 4th, 6th, ... time the button is pressed: add the text back
|
||||
text_state.eq(1) second_text = column.gui_add(Text: "i'm back!")
|
||||
text_state.eq(3) second_text = column.gui_add(Text: "you can't fully get rid of me!")
|
||||
true {
|
||||
second_text = column.gui_add(Text: "i always come back")
|
||||
// restart (set text_state to 0)
|
||||
text_state = -1
|
||||
}
|
||||
}
|
||||
text_state = text_state.add(1)
|
||||
}
|
||||
true println("A different button was pressed (unreachable)")
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
[]
|
||||
}
|
||||
17
examples/http.mers
Normal file
17
examples/http.mers
Normal file
@@ -0,0 +1,17 @@
|
||||
lib mers_libs/http_requests
|
||||
|
||||
t = thread(() {
|
||||
// because this downloads for so long, the println() will appear after the other one.
|
||||
http_get("https:\//raw.githubusercontent.com/dwyl/english-words/master/words.txt").assume_no_enum()
|
||||
println("got words from word list!")
|
||||
})
|
||||
|
||||
sleep(0.1)
|
||||
|
||||
// this will finish before the thread does.
|
||||
http_get("https:\//github.com/").assume_no_enum()
|
||||
println("got github start page as html")
|
||||
|
||||
t.await()
|
||||
|
||||
http_get("not a url").debug()
|
||||
39
examples/iterators.mers
Executable file
39
examples/iterators.mers
Executable file
@@ -0,0 +1,39 @@
|
||||
fn map_string_to_int(list [string ...] func fn((string int))) {
|
||||
// return a function that can be used as an iterator
|
||||
() {
|
||||
// this function will be called by the for loop
|
||||
// whenever it wants to retrieve the next item in the collection.
|
||||
// get the element
|
||||
elem = &list.remove(0)
|
||||
switch! elem {
|
||||
// if the element was present, run the map function to convert it from a string to an int and return the result
|
||||
[string] {
|
||||
[func.run(elem.0)]
|
||||
}
|
||||
// if there are no more elements, return something that doesn't match.
|
||||
[] []
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
for v ["1" "2" "5" "-10" ...].map_string_to_int((s string) s.parse_int().assume1("list contained strings that can't be parsed to an int!")) {
|
||||
debug(v)
|
||||
}
|
||||
|
||||
|
||||
// returns an iterator to iteratively compute square numbers
|
||||
// using the fact that (n+1)^2 = n^2 + 2n + 1
|
||||
fn square_numbers() {
|
||||
i = 0
|
||||
val = 0
|
||||
() {
|
||||
val = val + { 2 * i } + 1
|
||||
i = i + 1
|
||||
[val]
|
||||
}
|
||||
}
|
||||
|
||||
for n square_numbers() {
|
||||
println(n.to_string())
|
||||
n >= 100
|
||||
}
|
||||
8
examples/macro.mers
Executable file
8
examples/macro.mers
Executable file
@@ -0,0 +1,8 @@
|
||||
val = "some string"
|
||||
val = !(mers {
|
||||
println("macro is running now!")
|
||||
"macro returned value"
|
||||
})
|
||||
println(val)
|
||||
val = !(mers "my_macro.mers")
|
||||
println(val)
|
||||
74
examples/mersrandr.mers
Executable file
74
examples/mersrandr.mers
Executable file
@@ -0,0 +1,74 @@
|
||||
lib mers_libs/gui
|
||||
|
||||
// GUI for xrandr, because arandr doesn't let me change the framerates.
|
||||
// [ WIP ]
|
||||
|
||||
base = gui_init()
|
||||
|
||||
set_title("MersRandr")
|
||||
|
||||
randr_output = run_command("xrandr")
|
||||
|
||||
switch! randr_output {
|
||||
Err(string) {
|
||||
println(randr_output.noenum())
|
||||
}
|
||||
[[]/int string string] {
|
||||
lines = randr_output.1.regex(".*")
|
||||
screen_name = ""
|
||||
screen_resolutions = [["" ["" ...]] ...]
|
||||
screens = [
|
||||
[
|
||||
screen_name
|
||||
screen_resolutions
|
||||
]
|
||||
...]
|
||||
&screen_resolutions.pop()
|
||||
&screens.pop()
|
||||
for line lines {
|
||||
if line.starts_with("Screen ") {
|
||||
// ignore
|
||||
} else if line.starts_with(" ") {
|
||||
// split at spaces (and ignore +*)
|
||||
refresh_rates = line.regex("[^ +\\*]+").assume_no_enum()
|
||||
resolution = &refresh_rates.remove(0).assume1()
|
||||
print("{0} ::".format(resolution))
|
||||
for rate refresh_rates {
|
||||
print(" \"{0}\"".format(rate))
|
||||
}
|
||||
&screen_resolutions.push([resolution refresh_rates])
|
||||
println("")
|
||||
} else {
|
||||
index = line.index_of(" ")
|
||||
switch! index {
|
||||
int {
|
||||
if not(screen_name.len().eq(0)) {
|
||||
&screens.push([screen_name screen_resolutions])
|
||||
}
|
||||
screen_resolutions = [ ...]
|
||||
screen_name = line.substring(0 index)
|
||||
println("> \"{0}\"".format(screen_name))
|
||||
}
|
||||
[] {}
|
||||
}
|
||||
}
|
||||
}
|
||||
if not(screen_name.len().eq(0)) {
|
||||
&screens.push([screen_name screen_resolutions])
|
||||
}
|
||||
for screen screens {
|
||||
println(screen.0)
|
||||
gui_screen = base.gui_add(Row: [])
|
||||
gui_name = gui_screen.gui_add(Text: screen.0)
|
||||
for res screen.1 {
|
||||
gui_resolution = gui_screen.gui_add(Button: res.0)
|
||||
print(" ")
|
||||
println(res.0)
|
||||
for rate res.1 {
|
||||
print(" ")
|
||||
println(rate)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
205
examples/musicdb_remote.mers
Executable file
205
examples/musicdb_remote.mers
Executable file
@@ -0,0 +1,205 @@
|
||||
lib mers_libs/http_requests
|
||||
lib mers_libs/gui
|
||||
|
||||
// MusicDB is a private project of mine.
|
||||
// Basically, a SBC is hooked up to some speakers.
|
||||
// It has a database of my songs and can play them.
|
||||
// It can be controlled through HTTP requests, such as
|
||||
// p- to stop
|
||||
// p+ to play
|
||||
// qi to get the queue index / playback position
|
||||
// l to list all the songs
|
||||
// ql or qL to list the queue
|
||||
// ...
|
||||
// this mers program should work as a very simple gui to remotely control
|
||||
// the playback of songs. It should be able to add/remove songs to/from the queue,
|
||||
// to start/stop playback, and to display some information about the current song.
|
||||
|
||||
// the url used to connect to the SBC and use the HTTP api
|
||||
api_url = "http:\//192.168.2.103:26315/api/raw?"
|
||||
|
||||
// start the GUI
|
||||
base = gui_init()
|
||||
set_title("Mers MusicDB Remote")
|
||||
|
||||
playback_controls = base.gui_add(Row: [])
|
||||
play_button = playback_controls.gui_add(Button: "Play")
|
||||
stop_button = playback_controls.gui_add(Button: "Stop")
|
||||
|
||||
// these functions abstract away the api interactions
|
||||
// because they aren't pretty.
|
||||
// feel free to skip past this section and look at the gui code instead
|
||||
fn make_api_request(to_api string) {
|
||||
http_get(api_url.add(to_api))
|
||||
}
|
||||
fn get_queue_index() {
|
||||
r = make_api_request("qi")
|
||||
switch! r {
|
||||
string {
|
||||
r.regex("[0-9]").assume_no_enum().get(0).assume1().parse_int().assume1()
|
||||
}
|
||||
// return the error
|
||||
Err(ErrBuildingRequest(string)/ErrGettingResponseText(string)) r
|
||||
}
|
||||
}
|
||||
fn get_db_contents() {
|
||||
// list only 7 = 1 (title) + 2 (artist) + 4 (album)
|
||||
r = make_api_request("lo7,")
|
||||
switch! r {
|
||||
string {
|
||||
entries = r.regex("#.*:\n.*\n.*\n.*").assume_no_enum()
|
||||
// initialize the list with a default value
|
||||
// because mers doesnt know the inner type without it.
|
||||
db = [[0 "title" "artist" "album"] ...]
|
||||
&db.remove(0)
|
||||
for entry entries {
|
||||
lines = entry.regex(".*")
|
||||
switch! lines {
|
||||
[string ...] {
|
||||
index_line = &lines.get(0).assume1()
|
||||
index = index_line.substring(1 index_line.len().sub(1)).parse_int().assume1()
|
||||
title = &lines.get(1).assume1().substring(1)
|
||||
artist = &lines.get(2).assume1().substring(1)
|
||||
album = &lines.get(3).assume1().substring(1)
|
||||
&db.push([index title artist album])
|
||||
}
|
||||
Err(string) {
|
||||
println("invalid response from server; 3u123128731289")
|
||||
exit(1)
|
||||
}
|
||||
}
|
||||
}
|
||||
db
|
||||
}
|
||||
Err(ErrBuildingRequest(string)/ErrGettingResponseText(string)) {
|
||||
println("couldn't request db from server:")
|
||||
print(" ")
|
||||
println(r.to_string())
|
||||
exit(1)
|
||||
}
|
||||
}
|
||||
}
|
||||
fn get_queue() {
|
||||
r = make_api_request("ql")
|
||||
switch! r {
|
||||
string {
|
||||
queue = [0 ...]
|
||||
&queue.remove(0)
|
||||
for index r.regex("[0-9]+[ \n]").assume_no_enum() {
|
||||
&queue.push(index.substring(0 index.len().sub(1)).parse_int().assume1())
|
||||
}
|
||||
queue
|
||||
}
|
||||
Err(ErrBuildingRequest(string)/ErrGettingResponseText(string)) {
|
||||
println("couldn't request queue from server:")
|
||||
print(" ")
|
||||
println(r.to_string())
|
||||
exit(1)
|
||||
}
|
||||
}
|
||||
}
|
||||
fn play() {
|
||||
r = make_api_request("p+")
|
||||
switch! r {
|
||||
// success! but nothing to return.
|
||||
string []
|
||||
// return the error
|
||||
Err(ErrBuildingRequest(string)/ErrGettingResponseText(string)) r
|
||||
}
|
||||
}
|
||||
fn stop() {
|
||||
r = make_api_request("p-")
|
||||
switch! r {
|
||||
// success! but nothing to return.
|
||||
string []
|
||||
// return the error
|
||||
Err(ErrBuildingRequest(string)/ErrGettingResponseText(string)) r
|
||||
}
|
||||
}
|
||||
fn queue_song(song_id int) {
|
||||
make_api_request("q+{0}".format(song_id.to_string()))
|
||||
}
|
||||
|
||||
// fetch the database contents (a list of songs)
|
||||
database = get_db_contents()
|
||||
|
||||
// this is where all the songs will be displayed.
|
||||
songs_gui = base.gui_add(Row: [])
|
||||
queue_list = songs_gui.gui_add(Column: [])
|
||||
library = songs_gui.gui_add(Column: [])
|
||||
|
||||
limit = 0 // set to 0 to disable library length limit
|
||||
for entry database {
|
||||
// <SONG> by <ARTIST> on <ALBUM>
|
||||
song = library.gui_add(Row: [])
|
||||
song.gui_add(Button: entry.1)
|
||||
song.gui_add(Text: "by {0} on {1}".format(entry.2 entry.3))
|
||||
limit = limit.sub(1)
|
||||
if limit.eq(0) [[]] else []
|
||||
}
|
||||
|
||||
// regularly update the queue
|
||||
thread(() {
|
||||
queue_index = get_queue_index().assume_no_enum("if the server isn't reachable, it's ok to crash")
|
||||
queue_list_inner = queue_list.gui_add(Column: [])
|
||||
prev_artist = ""
|
||||
prev_album = ""
|
||||
for song_id get_queue() {
|
||||
this_is_playing = if queue_index.eq(0) { queue_index = -1 true } else if queue_index.gt(0) { queue_index = queue_index.sub(1) false } else { false }
|
||||
song = &database.get(song_id).assume1()
|
||||
row = queue_list_inner.gui_add(Row: [])
|
||||
text = if this_is_playing ">> " else ""
|
||||
text = text.add(song.1)
|
||||
if prev_artist.eq(song.2) {
|
||||
if prev_album.eq(song.3) {
|
||||
} else {
|
||||
text = text.add("(on {0})".format(song.3))
|
||||
}
|
||||
} else {
|
||||
text = text.add("(by {0} on {1})".format(song.2 song.3))
|
||||
}
|
||||
row.gui_add(Text: text)
|
||||
[]
|
||||
}
|
||||
sleep(10)
|
||||
queue_list_inner.gui_remove()
|
||||
})
|
||||
|
||||
loop {
|
||||
for event gui_updates() {
|
||||
switch! event {
|
||||
ButtonPressed([int ...]) {
|
||||
e = event.noenum()
|
||||
println("Pressed button {0}".format(e.to_string()))
|
||||
match e {
|
||||
&e.eq(&play_button) {
|
||||
println("pressed play.")
|
||||
play()
|
||||
}
|
||||
&e.eq(&stop_button) {
|
||||
println("pressed stop.")
|
||||
stop()
|
||||
}
|
||||
{
|
||||
// the button is in a row that is in the library,
|
||||
// so pop()ing twice gets the library path.
|
||||
// THIS WILL BREAK IF THE GUI LIBRARY SWITCHES TO IDs INSTEAD OF PATHS!
|
||||
last = &e.pop().assume1()
|
||||
slast = &e.pop().assume1()
|
||||
matches = &e.eq(&library)
|
||||
&e.push(slast)
|
||||
&e.push(last)
|
||||
if matches e else []
|
||||
} {
|
||||
// the second to last part of the path is the row within library, which is also the index in the db
|
||||
song = &database.get(&e.get(e.len().sub(2)).assume1()).assume1()
|
||||
println("Added song \"{0}\" to queue.".format(song.1))
|
||||
queue_song(song.0)
|
||||
}
|
||||
true println("A different button was pressed (unreachable)")
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
[]
|
||||
}
|
||||
2
examples/my_macro.mers
Executable file
2
examples/my_macro.mers
Executable file
@@ -0,0 +1,2 @@
|
||||
println("my macro running in ./my_macro.mers")
|
||||
"value returned from ./my_macro.mers :)"
|
||||
37
examples/thread.mers
Executable file
37
examples/thread.mers
Executable file
@@ -0,0 +1,37 @@
|
||||
// this is true by default so the example doesn't finish too quickly or too slowly depending on your hardware.
|
||||
// you can set it to false and tweak the max value for a more authentic cpu-heavy workload.
|
||||
fake_delay = true
|
||||
|
||||
// this will be shared between the two threads to report the progress in percent (0-100%).
|
||||
progress = 0
|
||||
|
||||
// an anonymous function that sums all numbers from 0 to max.
|
||||
// it captures the progress variable and uses it to report its status to the main thread, which will periodically print the current progress.
|
||||
// once done, it returns a string with the sum of all numbers.
|
||||
calculator = (max int) {
|
||||
sum = 0
|
||||
for i max {
|
||||
i = i + 1
|
||||
// println("i: {0}".format(i.to_string()))
|
||||
println("i: {0} s: {1}".format(i.to_string() sum.to_string()))
|
||||
sum = sum + i + 1
|
||||
if fake_delay sleep(1)
|
||||
v = i * 100 / max
|
||||
}
|
||||
"the sum of all numbers from 0 to {0} is {1}!".format(max.to_string() sum.to_string())
|
||||
}
|
||||
|
||||
// start the thread. if fake_delay is true, calculate 1+2+3+4+5+6+7+8+9+10. if fake_delay is false, count up to some ridiculously large number.
|
||||
slow_calculation_thread = calculator.thread(if fake_delay 10 else 20000000)
|
||||
|
||||
// every second, print the progress. once it reaches 100%, stop
|
||||
loop {
|
||||
sleep(1)
|
||||
println("{0}%".format(progress.to_string()))
|
||||
progress == 100 // break from the loop
|
||||
}
|
||||
|
||||
// use await() to get the result from the thread. if the thread is still running, this will block until the thread finishes.
|
||||
result = slow_calculation_thread.await()
|
||||
|
||||
println("Thread finished, result: {0}".format(result))
|
||||
Reference in New Issue
Block a user