Skip to content

Latest commit

 

History

History
1593 lines (1083 loc) · 21.4 KB

scratch.org

File metadata and controls

1593 lines (1083 loc) · 21.4 KB

important

string prefixes

‘S’ prefix automatically gives you a ‘String’ type, that then dispatches to GrowingString typically.

using import String

# new way
let s = S"hello"

# old way
let s_old = (String "hello")

print s
print (typeof s)

Single char prefix:

using import UTF-8

print c"h"

str prefix for the old “string” type.

let str_s = str"hello"
let s = "hello"

print (typeof str_s)
print (typeof s)

print (constant? str_s)
print (constant? s)


# print (string-constant? str_s)
# print (string-constant? s)

print (constant? (& str_s))
print (typeof (& str_s))

zarray

  • for array types that are guaranteed to be zero terminated
  • string literals are zarray by default

Constant strings

using import String

let cs = (sc_const_string_new "hello")

print (typeof cs)

comma operator

raw strings

& should cast a constant String to zarray

let str = "hello"

print (typeof str)
print (typeof &str)

using import String

let Str = (String "hello")

print (typeof &Str)

string formatting

using import format

print (format "Hello {}" "Bob")

Function type signatures

fn test (thing other)
    """"Test
    thing

print ('docstring test)
fn... test-types (thing : i32, other : f32)
    """"Test types
    print thing
    print other

test-types 0 0.2

print ('docstring test-types)
fn... test-types
case (thing : i32, other : f32)
    print thing
    print other

test-types 0 0.2

borrow checker

normal function signature:

using import struct

struct Thing
    i : i32
    j : i32

fn test-views (thing1 thing2)
    viewing thing1 thing2

    print (qualifiersof thing1)
    print (qualifiersof thing2)

    # thing.i = 1
    print thing1.i
    print thing2.i


let thing1 =
    Thing
        0
        1
let thing2 =
    Thing
        0
        2

print (qualifiersof thing1)

test-views thing1 thing2

Overloaded function definition:

using import struct

struct Thing
    i : i32
    j : i32

fn... test-views
case (thing : Thing)
    viewing thing

    print (qualifiersof thing)

    print thing.i
    print thing.j


let thing =
    Thing
        0
        1

# (uniqueof thing -1)
print (qualifiersof thing)

test-views thing

Mutate in a function:

using import struct

struct Thing
    i : i32
    j : i32

fn test-views (thing : Thing)
    # viewing thing

    print (qualifiersof thing)

    print thing.i
    print thing.j


let thing =
    Thing
        0
        1

# (uniqueof thing -1)
print (qualifiersof thing)

test-views thing

Note that for inlines you don’t need to declare viewing since it is a macro and the ownership never leaves the calling scope. But note that this means you can’t actually pass a view into an inline.

using import struct

struct Thing
    i : i32
    j : i32

inline test-views (thing : Thing)

    # NOTE you will get some kind of error with this
    # viewing thing

    print (qualifiersof thing)

    print thing.i
    print thing.j


let thing =
    Thing
        0
        1

# (uniqueof thing -1)
print (qualifiersof thing)

test-views thing

Overloaded constructor

as a classmethod

using import struct
struct Thing
    t : i32

    inline from-config (cls t)
        super-type.__typecall cls
            t = t

let thing = ('from-config Thing 0)

print thing

as an overloaded constructor

using import struct
struct Thing
    t : i32

    inline... __typecall
    case (cls, t : i32)
        super-type.__typecall cls
            t = t
    case (
        cls,
        t : i32,
        message : string,
    )

        print message
        super-type.__typecall cls
            t = t

let t0 = (Thing 0)
let t1 = (Thing 0 "hello")

print t0.t
print t1.t

# let thing = ('from-config Thing 0)
# print thing

var args

let x... = (_ 1 2)

print x...
print (va-countof x...)
let x... = '(1 2)

print (va-countof x...)

Methods

using import struct

# type Class < Struct
struct Class < Struct
    value : i32

    inline __typecall (cls value)
        super-type.__typecall cls
            value = value

    fn show (self)
        print self.value

    fn ret (self)
        self.value

    # define

let c =
    Class
        3

('show c)
print ('ret c)
using import struct

struct New < Struct
    test : i32

let n =
    New
        3

functional programming

print (((x) -> x + 1) 4)
inline genfunc ()
    fn hello ()
        print "hello"


let hello = (genfunc)

hello;
inline gen-genfunc ()
    inline genfunc ()
        fn hello ()
            print "hello"


let genfunc = (gen-genfunc)
let hello = (genfunc)

hello;

level 2 enums

plain vs regular enum

using import enum

enum Things2 plain
    A
    B

print Things2.A
print (superof Things2)

memory management stuff (level 2)

  • `copy`
  • `move`
  • `&` references
  • `view`
  • `dupe`
  • `lose`
  • `viewing`
  • `uniqueof`
local a = 3
local b = a

print (& a)
print (& b)

And-Or

(? true x y) = 10
fn give-bool ()
    return true

using import struct

struct Thing
    isit : bool

let thing =
    Thing
        (isit = true)


if (bool; and thing.isit)
    print "hello"
else
    print "nope"

Scopes

Merge 2 scopes

vvv bind a
do
    let thing1 = 0
    locals;

vvv bind b
do
    let thing2 = 1
    locals;

let final = (.. a b)
run-stage;

print final.thing2
;
# run-stage;

# # inline merge-scopes (scope-A scope-B)

# #     fold (scope = (Scope)) for k v in scope

# let scope1 =
#     fold (scope = (Scope)) for k v in a
#         'bind scope (k as Symbol) v


# run-stage;
# print scope1.thing1

# let scope2 =
#     fold (scope = scope1) for k v in b
#         'bind scope (k as Symbol) v

# run-stage;

# print scope2.thing1
# print scope2.thing2

Function for two scopes:

vvv bind a
do
    let thing1 = 0
    locals;

vvv bind b
do
    let thing2 = 1
    locals;

inline merge-scopes (scope_a scope_b)
    let tmp_scope =
        fold (scope = (Scope)) for k v in scope_a
            'bind scope (k as Symbol) v

    fold (scope = tmp_scope) for k v in scope_b
        'bind scope (k as Symbol) v

run-stage;

let final = (merge-scopes a b)

run-stage;

print final.thing1
print final.thing2

Generalized into a function for arbitrary scopes

TODO

inline merge-scopes (scope_a scope_b)

    let final =
        for scope in '(scope_a scope_b)
          


vvv bind a
do
    let thing1 = 0
    locals;

vvv bind b
do
    let thing2 = 1
    locals;

run-stage;

let final = (merge-scopes a b)

run-stage;

print final.thing1
print final.thing2
;
let macros = ('bind-symbols (Scope) (a = "hello"))

run-stage;

print macros.a
let scope =
    'bind-symbols (Scope)
        message = "hello"
        name = "Bob"

run-stage;

print (typeof scope)
print scope.name
;
let sc =
    do
        let
            x = 1
            y = "Hello"
        locals;

print sc.x
print sc.y

Loop over a scope

let sc =
    do
        let
            x = 1
            y = "Hello"
        locals;

run-stage;

for k v in sc
    print k "=" v

Test if a symbol is in a scope

let sc =
    do
        let
            x = 1
            y = "Hello"
        locals;

run-stage;

let test_sym = 'x

local success = false

for k v in sc
    if ((k as Symbol) == test_sym)
        success = true
        break;
print success

llvm debug GDB

let llvm.debugtrap = (extern 'llvm.debugtrap (function void))

expand C macros

vvv bind C:ctype
include
    """"#include <ctype.h>
        typeof(iscntrl('a')) patched_iscntrl(char c) {
            return iscntrl(c);
        }


using import UTF-8

print (C:ctype.extern.patched_iscntrl (char32 "a"))

Option

using import Option
using import struct

struct Thing global
    always : i32
    sometimes : (Option i32)

let t1 =
    Thing
        1
        2

let t2 =
    Thing
        1
        none

print t1.sometimes
print t2.sometimes

let result =
    try ('unwrap (t1 . sometimes))
    else
        # error "unwrap failed"
        print "unwrap failed"
        0

let result =
    try ('unwrap (t2 . sometimes))
    else
        error "unwrap failed"
;
using import Option

global option : (Option i32)

option = 2

hiden inline

The “hidden” named inline which doesn’t have a lifetime scope

inline hidden ()
    defer print "inline destructor"
    print "body of inline"

print "Calling inline"
hidden;
print "After inline"

static-assert

static-assert

misc

  

dunno

fn log (msg)
    (print (.. "===>" msg))

log "hjello"
...
print ::

Testing some fancy slicing syntax I’m making up:

let arr = [[0 1 2] [3 4 5]]

# basics
(fslice arr 0 2)
(fslice arr 0 :)
(fslice arr 0-1 ...)
(fslice arr (0 2) ...)

let arr = ndarray
    [[0 1 2]
     [3 4 5]]

let arr = ndarray
    0 1 2
        0 1 2
    3 4 5
        3 4 5

unpack

fn trio (a b c)
    print a
    print b
    print c

let a = '(0 1 2)

trio (unpack a)

Pass

Instead of a python pass:

fn nothing ()

nothing;

Do block

do
    print "hello"

forloop

Why doesn’t this work?

for i in (range 10)
    if (i == 1)
        print "continuing"
        continue;
    elseif (i > 2)
        print "breaking"
        break;

    print i

vvv colors

vvv bind Colors
do
    let
        LIGHTGRAY =  '(200, 200, 200, 255)
        GRAY = '(130, 130, 130, 255)
        DARKGRAY = '(80, 80, 80, 255)
        YELLOW = '(253, 249, 0, 255)
        GOLD = '(255, 203, 0, 255)
        ORANGE = '(255, 161, 0, 255)
        PINK = '(255, 109, 194, 255)
        RED = '(230, 41, 55, 255)
        MAROON = '(190, 33, 55, 255)
        GREEN = '(0, 228, 48, 255)
        LIME = '(0, 158, 47, 255)
        DARKGREEN = '(0, 117, 44, 255)
        SKYBLUE = '(102, 191, 255, 255)
        BLUE = '(0, 121, 241, 255)
        DARKBLUE = '(0, 82, 172, 255)
        PURPLE = '(200, 122, 255, 255)
        VIOLET = '(135, 60, 190, 255)
        DARKPURPLE = '(112, 31, 126, 255)
        BEIGE  = '(211, 176, 131, 255)
        BROWN = '(127, 106, 79, 255)
        DARKBROWN = '(76, 63, 47, 255)
        WHITE = '(255, 255, 255, 255)
        BLACK = '(0, 0, 0, 255)
        BLANK = '(0, 0, 0, 0)
        MAGENTA = '(255, 0, 255, 255)
        RAYWHITE = '(245, 245, 245, 255)

logging sugar

sugar log (body...)
    qq
        do
            print "Start"
            unquote-splice body...
            print "End"

run-stage;

(log (print "work"))

defer

defer print "end of module"
let a = (1 + 3)

print a

array of structs

using import struct
using import String
using import Array

struct Dog
    name : String
    bark : String = "woof"
    height : f32

local dog-arr = ((array Dog 2))

print ((dog-arr @ 0) . bark)
# print dog-arr

;

Array

using import Array

let a = ((Array i32) 1 2)

print (countof a)
let a = (arrayof i32 0 1)

print (typeof a)

void return type

fn dovoid ()

print (typeof (dovoid))
fn dothing ()
    1 + 1

print (typeof dothing)

itertools pipeline, UTF en/decode

using import itertools
let utf = (import UTF-8)

fn utf8-encode (arr)
    ->>
        arr
        utf.encoder
        string.collector ((countof arr) * (sizeof i32))

local src = (arrayof i32 63:i32 97:i32)

let dst = (utf8-encode src)

print dst

encode a single character:

using import itertools
let utf = (import UTF-8)

fn utf8-char-encode (ch)
    local arr = (arrayof i32 ch)
    ->>
        arr
        utf.encoder
        string.collector (sizeof i32)

local src = (arrayof i32 63:i32 97:i32)

let src = (63:i8 as i32)

let dst = (utf8-char-encode src)

print dst

exceptions

using import struct

struct myException
    what : string

try
    raise (myException "an error occurred")
except (e)
    print e.what

Indexing for-loop

The range is not constant so you can’t do something like this:

let things = (tupleof "a" "b" "c")

for i in (range (countof things))
    print (things @ i)

You also can’t do this:

let things = (tupleof "a" "b" "c")

for thing in things
    print thing

But you can do:

using import itertools
using import Array

let things = ((Array string) "a" "b" "c")

for idx thing in (zip (range (countof things)) things)
    print (tostring idx) thing

Bools

if (true and true)
    print "in there"

fold

You can’t really do this with mutability. Thats not what the fold is for.

using import Array

let things = ((Array i32) 1 2 3 4)

let new-things =
    fold (new-things = ((Array i32))) for thing in things
        let new-thing = (thing + 1)
        'append new-things new-thing

This is almost there but you need to cast the Value to an int:

let things = '(0 1 2 3)

let new-things =
    fold (new-things = (list)) for thing in things
        let new-thing = ((thing as i32) + 1)
        cons new-thing new-things

print new-things

Lets see if a non-collection can make the point here and later we can show it with a Scope:

let input = 0

let result =
    fold (result = input) for i in (range 3)
        result + 1

print result

docstrings

""""number
let a = 3
let scope = (sugar-eval sugar-scope)


print ('docstring scope 'a)

report

let a = 3

report a

print a

exit & abort

exit
;
fn explain-func (a b c)
    print _:

explain-func 0 1 2

Constant vs Dynamic

fn hello ()
    print "Hello"

inline run (func)
    (func)

run hello
fn hello ()
    print "Hello"

fn run (func)
    (func)

# ERROR
# run hello

static-typify

fn a ()
    none

let t = (static-typify a)

print t
print (typeof t)

branching types

if true
    "yellow"
else
    3
fn raise-error ()
    raising Error

    if true
        # raise (myException "an error occurred")
        error "error"

    else
        "no error"

print (static-typify raise-error)

# try
#     raise-error;
# except (e)
#     print "error occured"
#     "error"

;
(bind a) 3

Bind is not really meant to be used without vvv:

Here is how to do it though.

embed
    bind a
    1

print a

SLN parens escape

(print \1 + 1)
print ((fn (x) \ x + 1) 4)

Any value can be an error:

try
    raise "error"
except (e)
    print "something bad happened:"
    print e

;
label finish
    for i in (range 10)
        for j in (range 10)
            if ((i + j) > 10)
                print i j
                print (i + j)
                merge finish
  • [X] For lambdas
print (((x) -> x + 1) 4)
  • [ ] more generally

copy

using import String

local a = (String "hello")

print a

local b = (copy a)

print b

b = (String "testing")

print b
print a
using import enum

enum Actions plain
    Nothing = 0
    Terminate = 1

print (tostring Actions.Nothing)

let action = Actions.Nothing

switch action
case Actions.Nothing
    print "doing nothing"

case Actions.Terminate
    print "Terminating"

default
    print "default"
using import enum

enum Actions plain
    Nothing = 0
    Terminate = 1

print (typeof Actions.Nothing)

Type Definitions

type T < s: new supertype T as subtype of s
type T < s : m: new plain type T as subtype of s, using storage type m
type T < s :: m: new unique type T as subtype of s, using storage type m
type T <: s: new plain type T as subtype of (superof s), using storage type (storageof s)
type T <:: s: new unique type type T as subtype of (superof s), using storage type (storageof s) 
type+ T extend the definition of type T; it's otherwise exactly like type, but you "reopen" the declarative scope, and any name bound there becomes a type attribute
type Int0 < i32

let i0 = ((Int0) 1)

print i0
typedef Int0 <: i32
# type Int1 <: i32
# type Int2 <:: i32
# typedef Int3 < string : i32


# print (typeof Int0)
# print ('storageof Int0)
# print ('superof Int0)
# print (getattr Int0 '__typecall)
# print ""

# print (typeof Int1)
# print ('storageof Int1)
# print ('superof Int1)
# print ""

# print (typeof Int2)
# print ('storageof Int2)
# print ('superof Int2)
# print ""

for typ in '(Int0 Int1 Int2)
    print (typeof typ)
    print ('storageof typ)
    print ('superof typ)