Skip to content

Commit

Permalink
better klang
Browse files Browse the repository at this point in the history
  • Loading branch information
codekansas committed Aug 21, 2024
1 parent 428cdc8 commit 7ddac09
Show file tree
Hide file tree
Showing 2 changed files with 117 additions and 100 deletions.
73 changes: 33 additions & 40 deletions examples/clean_up_cans.k
Original file line number Diff line number Diff line change
@@ -1,51 +1,44 @@
# This program is designed to get a robot to clean up soda cans.
from robot import move, ppo_standing, nn

action <Find {item}> {
notes {
prefer [Move quickly]
avoid [Bumping into other objects]
avoid [Moving too hastily]
avoid [Moving slowly or staying in the same place for a long time]
}

outcomes {
success [Found {item}]
failure [Haven't moved in a while]
retry [Actively looking for {item}]
}
fn pick_up_apple_manual() {
x = 30deg
y = 30deg
*move("left_arm", joint=2, pos=x + y)
}

action <Pick up {item}> {
outcomes {
success [Holding {item}]
failure [Knocked over {item}]
retry [Not holding {item}]
}
fn pick_up_apple() {
*nn(
“Pick up the apple”,
pos=[“Move hand close to the apple”],
neg=[“Move quickly”],
on_failure=pick_up_apple_manual,
)
}

action <Put {item} into {container}> {
outcomes {
success [{item} is inside {container} and we are not holding it]
failure [Dropped {item} outside the {container}]
retry [Still holding {item}]
fn random_arm_movement() {
for i : [1, 2, 3] {
*(
move("right_arm", joint=2, pos=30deg + i * 0.1rad),
move("right_arm", joint=3, pos=30deg + i * 0.5rad),
)
if (i > 1) {
move
}
}
}

action <Empty the soda can into the sink> {
outcomes {
success [Successfully emptied the soda can into the sink]
failure [Spilled soda outside the sink]
retry [There is still soda in the can]
counter = 0
flag = true
while counter < 5 {
*(
move("right_arm", joint=2, pos=30deg + flag ? 0.1rad : -0.1rad),
move("right_arm", joint=3, pos=30deg + flat ? 0.5rad : -0.5rad),
)
flag = !flag
counter += 1
}
}

loop {
<Find a soda can>
<Pick up the soda can>
<Find the sink>
<Empty the soda can into the sink>
<Find the recycling bin>
<Put the soda can into the recycling bin>
} until {
[No more soda cans]
fn main() {
// Run both functions in parallel
*(pick_up_apple(), ppo_standing(), random_arm_movement())
}
144 changes: 84 additions & 60 deletions klang/src/klang.pest
Original file line number Diff line number Diff line change
@@ -1,60 +1,84 @@
// Whitespace and comments.
WHITESPACE = _{ " " | "\n" | "\t" }
COMMENT = _{ ("//" ~ (!"\n" ~ ANY)* ~ "\n") | ("/*" ~ (!"*/" ~ ANY)* ~ "*/") | ("#" ~ (!"\n" ~ ANY)* ~ "\n") }

// Actions.
ACTION = { "action" }

// Outcomes
OUTCOMES = { "outcomes" }
SUCCESS = { "success" }
FAILURE = { "failure" }
RETRY = { "retry" }
HANDLER = { "handler" }

// Notes
NOTES = { "notes" }
PREFER = { "prefer" }
AVOID = { "avoid" }

// Loops
LOOP = { "loop" }
ACTIONS = { "actions" }
UNTIL = { "until" }

// Names
CHAR = { ASCII_ALPHANUMERIC | "." | "_" | "/" | "!" | "?" | " " | "," | "\"" | "\'" | "/" | "\\" }
VARIABLE = { LBRACE ~ CHAR+ ~ RBRACE }
ACTION_NAME = { "<" ~ NAME ~ ">" }
OUTCOME_NAME = { "[" ~ NAME ~ "]" }
NAME = { (CHAR | VARIABLE)+ }

// Braces.
LBRACE = { "{" }
RBRACE = { "}" }

// File input.
file_input = { SOI ~ stmt* ~ EOI }

// Statements.
stmt = { action_def_stmt | action_call_stmt | loop_stmt }

// Action statements.
action_def_stmt = { ACTION ~ ACTION_NAME ~ LBRACE ~ action_def_body ~ RBRACE }
action_def_body = { (notes_block | outcomes_block)+ }

// Notes.
notes_block = { NOTES ~ LBRACE ~ note* ~ RBRACE }
note = { (PREFER | AVOID) ~ OUTCOME_NAME }

// Outcomes.
outcomes_block = { OUTCOMES ~ LBRACE ~ (outcome)* ~ RBRACE }
outcome = { (SUCCESS | FAILURE | RETRY | HANDLER) ~ OUTCOME_NAME }

// Action calls.
action_call_stmt = { ACTION_NAME }

// Loops.
loop_stmt = { LOOP ~ LBRACE ~ actions_block ~ (RBRACE ~ UNTIL ~ LBRACE ~ condition)? ~ RBRACE }
actions_block = { action_call_stmt* }
condition = { OUTCOME_NAME* }
// Pest Grammar for the Custom Language

// The root rule that starts the parsing process.
program = _{ SOI ~ stmt* ~ EOI }

// Statements include function definitions, function calls, and other constructs.
stmt = _{ ( import_stmt | function_def | expr_stmt ) }

// Import statement
import_stmt = _{ "from" ~ IDENT ~ "import" ~ IDENT ~ ("," ~ IDENT)* }

// Function definition
function_def = _{ "fn" ~ IDENT ~ "(" ~ param_list? ~ ")" ~ block }

param_list = _{ (IDENT ~ "=" ~ expr) ~ ("," ~ IDENT ~ "=" ~ expr)* }

// Block of statements enclosed in curly braces
block = _{ "{" ~ stmt* ~ "}" }

// Expression statement
expr_stmt = _{ expr ~ ";"? }

// Expression (can be a function call, assignment, or binary operation)
expr = _{ (
function_call
| assignment
| binary_op
| unary_op
| literal
| loop
| COMMENT
| IDENT
) }

// Function call with potential async operator `*`
function_call = _{ ( async_call | standard_call ) }
async_call = _{ "*" ~ standard_call }
standard_call = _{ IDENT ~ "(" ~ arg_list? ~ ")" }
arg_list = _{ expr ~ ("," ~ expr)* }

// Containers
container = _{ list | dict
list = _{ "[" ~ expr ~ "," ~ expr ~ "]" }

// Assignment statement
assignment = _{ IDENT ~ "=" ~ expr }

// Binary operation (addition, subtraction, etc.)
binary_op = _{ expr ~ binary_operator ~ expr }
binary_operator = _{ "+" | "-" | "*" | "/" | "?" | ":" }

// Unary operation (negation, etc.)
unary_op = _{ unary_operator ~ expr }
unary_operator = _{ "-" | "!" }

// Literals include numbers and units like `30deg`, `0.1rad`
literal = _{ (
number_with_unit
| number
| string
| boolean
) }

number_with_unit = _{ number ~ unit }
unit = _{ "deg" | "rad" | "m" | "cm" | "mm" | "ft" | "in" }

number = @{ ASCII_DIGIT+ ~ ("." ~ ASCII_DIGIT+)? }
string = @{ "\"" ~ (!"\"" ~ ANY)* ~ "\"" }
boolean = _{ "true" | "false" }

// Identifiers (function names, variable names, etc.)
IDENT = @{ ASCII_ALPHANUMERIC+ }

// A loop with `for` and `while` constructs
loop = _{ ( for_loop | while_loop ) }

for_loop = _{ "for" ~ IDENT ~ ":" ~ range ~ block }
while_loop = _{ "while" ~ expr ~ block }

// Comments
COMMENT = _{ "//" ~ (!"\n" ~ ANY)* }

// Whitespaces
WHITESPACE = _{ " " | "\t" | "\n" | "\r" }

0 comments on commit 7ddac09

Please sign in to comment.