diff --git a/docs/syntax.md b/docs/syntax.md index e1bf878..bd958df 100644 --- a/docs/syntax.md +++ b/docs/syntax.md @@ -8,6 +8,23 @@ Substitute the output of a module into another module's arguments by enclosing t Access a variable by prefixing it's name with a `$` dollar sign. +## Data Types + +Kyn supports several data types: strings, integers, doubles (floating-point numbers), and lists. + +### Strings +Strings are enclosed in double quotes. +`let myString = "Hello, World!"` + +### Numbers +Numbers can be integers or doubles. +`let myInt = 42` +`let myDouble = 3.14` + +### Lists +Lists are ordered collections of values, enclosed in square brackets. +`let myList = [1, "two", 3.0, ["nested", "list"]]` + ## Input/Output ### print @@ -18,7 +35,7 @@ Example: `print "Hello!"` ### println -Prints all the arguments provided to the console, appending a newline after. +Prints all the arguments provided to theconsole, appending a newline after. Example: `println "Hello!"` @@ -30,25 +47,76 @@ Example: `input` (this does nothing but prompt the user) Another example: `let userInput = (input)` -## Data +## Variables and Data ### let -Defines a variable to the value provided. +Defines a variable to the value provided. If no value is provided, it defaults to an empty string. Example: `let myVar = "Hello!"` +Example: `let anotherVar` + +### concat + +Concatenates multiple strings or numbers together. + +Example: `println (concat "There are " 3 " apples.")` // Prints "There are 3 apples." + +## Indexed Operations + +You can access elements of lists and characters of strings by their index (starting from 0). + +### Get element + +Syntax: `(variable index)` + +```kyn +let myList = ["a", "b", "c"] +println (myList 1) // Prints "b" + +let myString = "hello" +println (myString 2) // Prints "l" +``` + +### Set element + +Syntax: `variable index = newValue` + +```kyn +let myList = ["a", "b", "c"] +myList 1 = "z" +println $myList // Prints ["a", "z", "c"] + +let myString = "hello" +myString 0 = "j" +println $myString // Prints "jello" +``` + +### size + +You can get the number of elements in a list or characters in a string using `size`. + +Syntax: `(variable size)` + +```kyn +let myList = [1, 2, 3, 4] +println (myList size) // Prints 4 + +let myString = "hello" +println (myString size) // Prints 5 +``` ## Computations ### math -Computes a mathematical expression. Supports addition (+), subtraction (-), multiplication (*), division (/), power to (^) and mod (%). +Computes a mathematical expression. Supports addition (+), subtraction (-), multiplication (*), division (/), power to (^) and mod (%). Follows order of operations. Example: `math 4 * 3 + 12 / 4 - 5 ^ 3` ### compare -Compares two values. Supports equal (==) and inequal (!=) on all values. Supports greater than (>), greater than or equal to (>=), lesser than (<), and lesser than or equal to (<=) for numbers. +Compares two values. Supports equal (==) and inequal (!=) on all values. Supports greater than (>), greater than or equal to (>=), lesser than (<), and lesser than or equal to (<=) for numbers. Returns "1" for true and "0" for false. ## Control Flow @@ -58,11 +126,11 @@ Exits the program with a return code. If no return code or an invalid return cod ### if -Runs a module. If the output of that module is 0 or "false", skips the code in that block. If an `else` block is provided after, that is running instead. Otherwise, the code inside the `if` block is ran. +Runs a block of code if a condition is true. An optional `else` block can be provided. The condition is considered true if it's not 0, "false", or an empty string/list. Example: -``` +```kyn if compare 1 == 1 { println "1 is the same as 1" } else { @@ -72,15 +140,43 @@ if compare 1 == 1 { ### while -Runs a module. If the output of that module is 0 or "false", skips the code in that block. Otherwise, loops the block until the module ran is 0 or "false". +Runs a block of code repeatedly as long as a condition is true. Example: -``` +```kyn let number = 0 -while compare $number <= 10 { - number = ($number + 1) +while compare $number < 10 { + number = (math $number + 1) println $number } ``` + +### fun + +Defines a function with a name, a list of arguments, and a body. + +```kyn +fun multiply a b { + return (math $a * $b) +} + +let product = (multiply 7 6) +println $product # Prints 42 +``` + +### return + +Exits a function, optionally returning a value. + +```kyn +fun myFunc { + println "doing stuff..." + return "done" + println "this will not print" +} + +let result = (myFunc) +println $result # Prints "doing stuff..." and then "done" +``` \ No newline at end of file diff --git a/src/datatypes/lists/lists.cpp b/src/datatypes/lists/lists.cpp index 1a1fde3..8030ed5 100644 --- a/src/datatypes/lists/lists.cpp +++ b/src/datatypes/lists/lists.cpp @@ -1,6 +1,5 @@ #include "lists.h" #include "../../error/error.h" -#include "../../modules/math/math.h" #include "../../data/data.h" #include "../../utils/trim/trim.h" #include "../../utils/evaluate/evaluate.h" @@ -47,7 +46,7 @@ Value handleListGet(const Value& subject, const std::vector& args) { error("List accessor must be an integer or \"size\""); return Value(); } - + int index = accessor.int_val; if (index < 0 || (size_t)index >= subject.list.size()) { error("List index out of bounds"); diff --git a/src/defs/defs.cpp b/src/defs/defs.cpp index 88f58f6..186dce7 100644 --- a/src/defs/defs.cpp +++ b/src/defs/defs.cpp @@ -232,7 +232,9 @@ std::vector split(std::string line) { char bracket_type = 0; for (char chr : line) { - if (chr == ' ' && !instring && brackets == 0 && !buf.empty()) { + if (chr == '#' && !instring) { + break; + } else if (chr == ' ' && !instring && brackets == 0 && !buf.empty()) { if (buf[0] == '$') { splitvals.push_back(Value(Varname(buf))); } else { diff --git a/src/modules/compare/compare.cpp b/src/modules/compare/compare.cpp index 105ad54..cf9a539 100644 --- a/src/modules/compare/compare.cpp +++ b/src/modules/compare/compare.cpp @@ -1,6 +1,5 @@ #include "compare.h" #include "../../error/error.h" -#include "../math/math.h" Value modules::compare(std::vector values) { if (values.size() != 3) { diff --git a/src/parser/parser.cpp b/src/parser/parser.cpp index 0bf3f17..6f03a1c 100644 --- a/src/parser/parser.cpp +++ b/src/parser/parser.cpp @@ -44,6 +44,11 @@ std::vector parse(std::string program) { continue; } + // Ignore commented lines + if (line[0] == '#') { + continue; + } + if (line.rfind("if", 0) == 0) { Instruction if_inst; if_inst.instruction = InstructionType::If; diff --git a/tests/let.kyn b/tests/let.kyn new file mode 100644 index 0000000..9384694 --- /dev/null +++ b/tests/let.kyn @@ -0,0 +1,3 @@ +let myVar = "hello there!" + +println $myVar