Browse Source

make an example script

tcheukueppo 2 years ago
parent
commit
640271ddcb
4 changed files with 179 additions and 6 deletions
  1. 25 6
      doc/syntax_reference.md
  2. 130 0
      example_scripts/fibonacci.pi
  3. 3 0
      go.mod
  4. 21 0
      test.go

+ 25 - 6
doc/syntax_reference.md

@@ -43,15 +43,16 @@ User can also use these delimiters to delimitate regular expressions.
 
 ## Extended unary operator
 
-- `say`: (b) print to the standard output with a new line at the end
+- `say`: (b) print to the standard output with a trailing new line
 - `print`: (b) print without a new line
+- `printf`: (b) print formatted string without adding a trailing new line
 - `@`: (b) length of (array, hash values, string)
 - `%`: (b) return keys of a hash in an array
-- `defined`: (b) check if a varible is `nil` and return true otherwise.
+- `defined`: (b) check if a varible is `nil` and return true otherwise
 
 # Binary operators
 
-- `,`, `->`: comma operator, use `->` for readability in the hash datastructure.
+- `,`, `:`: comma operator, and key-value separator infix operator
 - `!`: negation operator ex: `! true == false`
 - `=`: (i) Assignment Operator
 - `//`: (i) `a // b`, return `a` if set otherwise `b` (Perl feature)
@@ -67,7 +68,11 @@ User can also use these delimiters to delimitate regular expressions.
 
 # Special variables 
 
-## The ones with `$` prepended
+## Type I special variables
+
+Expand the content of special variables with `$`
+
+`"Running on #{$OS}".say`
 
 - `OS`: OS version on which `pity` was build
 - `_` : Topic variable, mostly in blocks
@@ -76,17 +81,31 @@ User can also use these delimiters to delimitate regular expressions.
 - `$`: pid of the current pity program
 - `0`: program name
 
+## Type II special variable
+
+Here, we donot expand the content of this variable `$`
+
+- `ARGV`: for cmd line args, it is an object of type `Array`
+- `ARGC`: represents the argument count, it is an object of type `Int`
+
 # Pity Objects 
 
 All types are objects and support a set of method specific/common to them.
 
 Paranthesis are optional in method and function call
 
-## Number
+## Int
+
+Let `i` be a variable whose content is an object of type `Int`, `i` supports
+the following public methods:
+
+- `i.times { BLOCK }`:
+
 
 ## String
 
-Let `s` be a string, `s` of type `String` supports the following methods
+Let `s` be a variable whose content is a object of type `String`, `s` of type
+`String` supports the following public methods:
 
 - `s.len`: return string length
 - `s.gt(s1)`: return true if `s` gt `s1` else false, see opts above

+ 130 - 0
example_scripts/fibonacci.pi

@@ -0,0 +1,130 @@
+#!/usr/bin/env perl
+
+# x is a global variable which can be accessed from other namespaces
+# ex: if we were in the namespace ONE::TWO then access 'a' with ONE::TWO::W
+# it is mandatory for globals to be uppercased
+global W = 2
+
+# fibonacci sequence with ret value cached
+fun fibonacci(n) is cached {
+   n < 2 ? n : _F_(n - 1) * _F_(n - 2)
+}
+
+# forever loop
+forever {
+   "Hello World".say
+}
+
+# async forever loop
+async forever {
+   ["Hello", "World"].each{ .uc.shuffle + _ }
+}
+
+# fun fibonacci asyncronously
+async fibonacci(10)
+
+# Working with blocks
+LABEL: {
+   say "block one"
+
+   # recurse to the current block
+   _BLOCK_ if "one".shuffle(3)  = "one"
+   # recurse to the current block too
+   _LABEL_ if "one".shuffle(3) = "one"
+
+   {
+      say "block two"
+
+      # recurse to LABEL
+      _LABEL_ if "two".shuffle(4) = "two"
+      # recurse to the current block
+      _BLOCK_
+   }
+}
+
+## Numbers
+3.times{ ... } # ...: unimplemented
+
+## Hash
+# declare a hash and store it in a lexically scope variable
+let bhash = {one: 2, two: 1} # or
+let ahash = Hash.new(
+                     2   -> two,
+                     3   -> "this three",
+                     one -> 1,
+                    ) # can replace '->' with ','
+
+# declaring a code/block
+let code = {
+   let(k, v) = (_[0], _[2])
+   say "#k, #{v isa Num ? v + 1 : v.uc }"
+}
+
+code(k, v) foreach k,v in ahash
+ahash.each_kv{ a.say; b.say }
+
+# _ is a topic variable
+hash.keys{ (_ + .lc).say }
+
+ahash{one}.say # accessing elements
+ahash{one, 2, 3}.each{ ... } # returns an array
+ahash{one, 2, 3} = ["One", 2, "ThReE"] # change values
+
+let key = "Hello"
+say ahash{key} if ahash.exists(key)
+
+del key # delete lexical var 'key'
+
+## Arrays
+let array  = ["one", 2, 3] # or
+let barray = Array.new("one", 2, 3)
+array.say
+array.each{ ... }.grep{ ... }
+
+let r = 3..4 # returns an array of values ranging from 3 to 4
+r.each { .say }
+
+# access values
+barray[0].say
+array[2..4].each({...})
+
+# lvalue
+array[0..1] = qw(i j)
+
+'a'..'z'.each{ ahash.exists(_) && .say }
+
+## Complex data structures
+let wtf = {
+   one   -> [ { two -> 3, three -> 4 }, [qw(a b c d)] ],
+   two   -> do { ... },
+   three -> True ? [ { one -> 1, two -> 2 } ] : do { ... },
+}
+
+let b = [wtf, True]
+
+## Working with Files
+const file = "/path/to/file"
+<file>.each_line{ .uc.say } # <a> open file "a" for reading if exists and return the File object
+<>.each_line{ ... } # read from standard input
+
+# flow constructs
+while (True) { ... }
+foreach v in array { ... }
+
+# classes
+class Person { ... }
+class Student << Person [, classA classB ] {
+   has class is rw
+   has notes is ro
+
+   # multiple dispatch
+   multi method get_nodes(v) {
+      self.notes.each{ _ > v}
+   }
+
+   multi method get_nodes(v, k) {
+      self.notes.each{x < _ < k}
+   }
+
+   ...
+}

+ 3 - 0
go.mod

@@ -0,0 +1,3 @@
+module test
+
+go 1.19

+ 21 - 0
test.go

@@ -0,0 +1,21 @@
+package main
+
+import (
+   "fmt"
+)
+
+var ast      = make([]any, 0)
+var prefix   = []string{"+", "-"}
+var op_codes = map[int8]any {
+                              0: []string{ "+", "-" },
+                              1: "/",
+                              2: "*",
+                              3: "(",
+                            }
+
+// 2 * + 4 / 2 - 1 --> ((2 * (+4)) / 2) - 1
+func main() {
+   expr := []any{2, "*", "+", 4, "/", 2, "-", 1}
+
+
+}