
Chika ist eine Programmiersprache, die sowohl Arduino als Firmware als auch Linux als ausführbare Datei abzielt. Es erleichtert hochrangige Rund-Robin-Multitasking-Programme und laden Programme entweder aus einer SD-Karte oder einem Linux-Dateisystem.
Sein Ziel ist es, sich sowohl über die Geschwindigkeit als auch über den Speicher Fußabdruck zu bewegt, mit einem einzigartigen Stapel-Speichermodell, der in LISP-inspirierten Syntax und einem internen Messaging im MQTT-Stil.
Sein Geist ist: Entkoppeln Sie alles durch Kommunikation zwischen den Aufgaben.
Besuchen Sie die Website für weitere Informationen , einschließlich Begründung, Vergleiche mit anderen Projekten, Fotos und mehr.
Besuchen Sie die Zwietracht, um zu chatten.
Weitere realistische Beispiele finden Sie im Core.chi und den Rest des Korpus.
Hinweis:; ;//… wird verwendet, um die Clojure -Syntax -Hervorhebung zu verwenden. Kommentare in Chika sind gerade //… .
; //Calculates Nth term of Fibonacci Sequence
( fn fib n
( if ( < n 3 ) 1 i
( + ( fib ( - n 1 )) ( fib ( - n 2 )))))
( fib 35 ) => 9227465
; //LED blink program for Arduino
( p-mode 32 T)
( fn heartbeat on
( dig-w 32 on)
( sleep 1000 w)
( ! on))
; //Prints `15`
( print
( do a= + b= 10 c= 5
( a b c)))
; //Prints `Hello!`
( fn my-print
( print str))
( do str= " Hello! "
( my-print ))
; //Filter function, found in core.chi
; //Note: `empty?`, `st`, `append`, and `odd?` are all implemented in Chika in core.chi
; //Note: `out` is an optional argument, as `append` accepts nil as a vector
( fn filter f v ; ; out
( if ( empty? v)
out
( do next= ( st v)
( recur f ( sect v)
( if ( f next)
( append out next)
out)))))
( filter odd? [ 0 1 2 3 ]) => [ 1 3 ]
; //Returns [15 9], using an inline-function with one argument - `#`
( map {# 12 3 } [+ -])
; //Subscribes to all inter-program messages to do with displays, and prints their payloads
( sub " display/+ " {print # 1 }) Öffnen Sie Chika_Arduino.ino in Arduino ide, laden Sie in Ihren Arduino hoch.
Stellen Sie sicher, dass eine SD -Karte mit der Datei init.kua eingefügt wird. Weitere Programme sollten in der init.kua -Datei mit dem load geladen werden.
Geeignete Geräte:
Derzeit gibt es einige Optionen zum Kompilieren und Ausführen von Chika unter Linux.
In dem Terminal können Sie ./compile.sh zur Neukompilierung von Chika VM für Ihre Maschine ausführen, wodurch der native Compiler auch corpus/programs/init.chi neu kompiliert.
Um eine Chika .chi -Quelldatei oder eine .kua -kompilierte Datei auszuführen, können Sie die ausführbare chika mit seinem Pfad aufrufen, z. B.: ./chika ../corpus/programs/fibonacci.chi . Dies wird fibonacci.chi als fibonacci.kua im Arbeitsverzeichnis der ausführbaren Datei zusammenstellen.
Quelldateien können mit einem Shebang an die ausführbare Chika -Datei vorbereitet werden, um eine .chi -Datei direkt auszuführen.
Auf dem PC: Rufen Sie die ausführbare chika -Datei wie ./chika c source.chi auf. Rufen Sie ohne das c -Flag ein, um die resultierende Datei zu kompilieren und dann auszuführen.
Auf PC/Arduino: Verwenden Sie das comp OP in Chika, um .chi -Quelldateien zu kompilieren.
HINWEIS: Auf dem Arduino kann eine Weile dauern, da es mit sehr begrenztem Speicher kompiliert und meistens jeweils ein Byte in eine Datei schreibt.
HINWEIS: Die Zusammenstellung gibt viele temporäre Dateien aus, die nach einer erfolgreichen Zusammenstellung gelöscht werden sollten.
Jedes in die VM geladene Programm hat eine Lebensdauer von:
All dies ist optional, aber zumindest muss ein Herzschlag oder Eintrag in einem Programm angegeben werden.
Der Eintrag wird Code zu Beginn des Programms vor Herzschlägen oder Nachrichten ausgeführt und ist in keiner Funktionen enthalten. Es kann Funktionen noch vor ihrer Erklärung in der Quelldatei aufrufen. Der letzte Eintrag gab den REIZUNGSREITEN den Programmstatus aus. Der Einstiegscode wird nach der Verwendung entladen, danach kann dies möglicherweise nicht aufgerufen werden.
Herzschläge sind erforderlich, um ein Programm zu stoppen, das nach dem Eintritt sofort endet, indem eine Funktion namens heartbeat aufgenommen wird. Dies wird pro Programm mit Herzschlagfunktion im Round-Robin-Stil ausgeführt. Die heartbeat wird der anhaltende Zustand des Programms als Parameter übergeben, und die Rendite wird als neuer Zustand bestehen.
Nachrichten werden im gesamten VM übertragen und führen alle Rückruffunktionen aus, haben auch den Status des Programms übergeben und den neuen Staat zurückgegeben.
Beschriftungen und Funktionsnamen können (fast) alle Zeichen ohne Whitespace enthalten.
Funktionsnamen dürfen nicht mit einer Ziffer beginnen.
#num : Erste Dateizeile nur (oder zweitens, wenn ein Schebang anwesend ist). Informiert die VM, wie viele Bytes RAM ( num bis 64 kib) vom Programm verwendet werden. Andernfalls wird ein Standardmaximum verwendet.
(func[ N args]) : eine Form mit einer Funktion in der Kopfposition und 0-N-Argumenten, die durch Räume getrennt sind. Argumente können Formen sein.
Hinweis: func kann eine native Operation, eine Programmfunktion, eine Inline-Funktion, eine Bindung, eine erweiterte Bindung, einen Parameter oder einen erweiterten Parameter sein.
(fn func-name[ N params] [1-N forms]) : Eine Funktionsdefinition mit 0-N-Parametersymbolen, die durch Leerzeichen getrennt sind, und 1-N-Formen.
Hinweis: Aufrufen einer Funktion ohne Formulare gibt NIL zurück.
{form} : Eine Inline-Funktion, die als eine Form besteht.
Hinweis: Parameter der umgebenden Funktionen können nicht in Inline-Funktionen verwiesen werden. Verwenden Sie stattdessen eine Bindung.
Hinweis: verschachtelte Inline-Funktionen sind verboten.
# : Eine Parameterreferenz auf den ersten Parameter einer Funktion.
$ : Eine erweiterte Parameterreferenz auf den ersten Parameter der Anruferfunktion einer Funktion.
#N und $N : Eine Parameterreferenz auf den N -ten Parameter, zB #3 oder $3 für den vierten Parameter entweder der Funktion oder in der Anruferfunktion der Funktion.
HINWEIS: Verwenden Sie $ , wenn keine Aufruffunktion ein undefiniertes Verhalten ist.
HINWEIS: Der Wert $ Referenzen kann durch die Heckqualitätenoptimierung gelöscht werden.
//… : Ein Kommentar, der auf einer neuen Zeile oder am Ende eines geeignet sein kann.
/*…*/ : Ein multiline Kommentar. Hinweis: Eine Instanz von */ wird einen Kommentar sofort beenden und nicht in einem multiline Kommentar selbst enthalten sein
; : Ein Semikolon, das als Whitespace behandelt wird.
, : Ein Komma, das als Whitespace und Whitespace behandelt wird, nachdem es gelöscht wurde.
…= : Bindung, wobei … ein Etikett ist.
… : Bindungsreferenz oder Parameterreferenz in Abhängigkeit vom Kontext, wobei … die Etikett ist.
.… : Eine erweiterte Bindungsreferenz, wobei … das Etikett ist. Es verweist auf die vorherige Instanz einer Bindung am Stapel.
HINWEIS: Parameter haben Präzedenzfälle gegenüber Bindungen pro Funktion.
Hinweis: Wenn Bindungen neu definiert werden , muss man eine erweiterte Bindung verwenden, sodass die VM die vorherige Instanz überspringt. Beachten Sie: a= (+ 1 .a) , so dass a in diesem Moment nicht auf den nächsten Element auf dem Stapel bezieht - 1 .
Die Funktionen, if && or , und case nicht in einer Bindung oder einem Parameter dargestellt werden können.
Da die Funktionen nur Formulare enthalten dürfen, stellen Sie sicher, dass die Rücksendungen val verwendet werden.
Hinweis: Ganzzahlen befinden sich entweder im hexadezimalen Format für Dezimal- oder Big-Endian.
"…" : String, wobei … 0 bis 128 ASCII -Zeichen oder "" für leer sind." und str für Doppelquoten, da Saiten keine entkommenen Zeichen liefern.0 oder 0x00 : 8-Bit nicht signierter Ganzzahl.0w oder 0x0000 : 16-Bit Unsigned Ganzzahl.0i oder 0x00000000 : 32-Bit signierte Ganzzahl.c : ASCII -Zeichen. Erweitert: nl Newline, sp Space.[…] : Vektor, wobei … 0 bis 2^16 Elemente durch den Raum oder [] für leer sind. Syntaktischer Zucker für (vec …) args : Emitiert einen Vektor von Funktionsargumenten.T : buchstäblicher Boolean wahrF : buchstäblicher boolean falschN : wörtlicher Null Hinweis: [square brackets] geben optionale Argumente an.
Mathematisch
+ / - / * / / % / ** /
& / | / ^ / << / >> n arg:
Gibt Summe / Subtraktion / Multiplikation / Division / Modul / Raise-to-the-Power / zurück
Und / oder / xor / linke Verschiebung / rechte Verschiebung von N -Zahlen.
Zero Args gibt Nil zurück. Wirft alle Parameter als Art des ersten Arguments.
~ n : Gibt bitweise nicht von n zurück.
Beispiele: (+ 1 1) => 2 , (+ 155 200) => 100 , (+ 155w 200) => 355w
rand : Gibt einen pseudo-random booleschen zurück.
rand b : Gibt eine Pseudo-Random-Ganzzahl von 0 bis b exklusiv zurück.
rand ab : Gibt eine Pseudo-Random-Ganzzahl von a inklusiven zu b exklusiv zurück.
HINWEIS: Negative a oder b bewirken, dass sie als 1 verstanden werden.
Bedingt
if cond if-true , bewertet und gibt es zurück, if-true cond wahr sind, sonst nil.
if cond if-true if-false : Bewertet und zurückgibt, if-true , wenn cond Eigentumswohnung ist, wird es sonst if-false .
case match … N pairs … [default] : Evalues match und vergleicht sich dann mit dem ersten jedes Argumentepaars, wobei der zweite wenn der erste übereinstimmt; Wenn keine Übereinstimmungen default werden oder NIL zurückgegeben wird.
! i : Negiert logisch negiert Element i .
or n arg: Gibt den ersten Wahrheit Arg.
&& n arg: Gibt wahr, wenn alle args wahrheitlich.
= N arg: Gleichheit, wahr, wenn alle Args von gleicher Art, Länge und Byte -Gleichheit sind. Vergleicht INTs nach Wert.
!= N arg: Negative Gleichheit.
== n arg: Eigenkapital gibt true zurück, wenn n Elemente von Byte -Gleichheit sind.
!== n arg: Negative Eigenkapital.
< / <= / > / >= N arg: Return true, wenn N-Elemente in monotoner zunehmender / nicht-dekretierender / abnehmender / nicht steigender Reihenfolge sind.
Funktionsbezogen
return[ val] : Beenden Sie eine Funktion frühzeitig und bewerten Sie entweder NIL oder val .
recur n Arg: Ersetzen Sie auf dem Stapel die Parameter durch N -Argumente und erinnern Sie sich an die Funktion.
val 1-N Arg: Gibt sein erstes Argument zurück.
do 1-N Arg: Gibt sein endgültiges Argument zurück.
String, Vektor und Blob im Zusammenhang
vec 0 Arg: Gibt einen leeren Vektor zurück.
vec N Arg: Gibt den Vektor seiner Argumente zurück.
nth N i : Gibt Element oder Zeichen bei Index N von Vector oder String i oder NIL zurück, wenn N in einem unsachgemäßen Bereich befindet.
str 0 Arg: Gibt leere Zeichenfolge zurück.
str n Arg: Rücksende die Verkettung von N -Argumenten als Zeichenfolge.
len i : Gibt entweder Vektor-, String- oder interne Elementlänge zurück.
sect v : Rückgabe v mit dem ersten Element (falls Vektor) oder Zeichen (falls String) weggelassen;
sect v skip : Rücksende v mit ersten skip von Elementen/Zeichen weggelassen;
sect v skip take : Rückkehr v mit Länge take und zuerst skip Elemente/Zeichen weggelassen;
..sect sect
blob ls : Gibt einen Blob Länge l mit allen Bytes zurück auf s .
get oltb : Gibt das Element des Typs t und der Länge l von Offset o -Bytes des b zurück.
get ob : Gibt den u08 -Wert von Byte bei Offset o Bytes von Element b zurück.
set oib : Gibt Blob b mit Offset o -Bytes zurück auf die Bytes von Punkt i .
HINWEIS: get set nil, wenn angefordert würde, dass Offset + Len die Größe des Blob überschreiten würde.
HINWEIS: Beide akzeptieren eine Referenz als b (z. *binding ) und inspizieren/ändern stattdessen die Bytes des ursprünglichen Referenzelements und set die Rückgabe der Referenz oder NIL fest.
.. v : Steckt einen Vektor oder eine Zeichenfolge v auf den Argumentstapel als Vektorelemente oder Zeichenelemente.
Hinweis: Wie in umgekehrter Clojure apply EG (+ (.. [1 2 3]) (.. [4 5 6])) => 21 .
Hinweis: Wenn sein Argument kein Vektor ist, hinterlässt es keine Elemente auf dem Stapel.
binds : Deduplikiert alle Bindungen in ihren Argumenten, begünstigt neuere und dann die Überreste.
Beispiel: (binds a= 1 b= 2 a= 3) => [b= 2 a= 3]
GPIO verwandt
Hinweis: Diese haben keinen Einfluss auf den PC.
p-mode pin mode : Legt den Modus der Pin -Number pin auf den Booleschen mode ein - Wahrheit als Eingabe, Falsey als Ausgabe; kehrt nil zurück.
dig-r pin : Gibt den digitalen Eingangszustand des Pin-Number pin zurück.
dig-w [1-N pin val] pin val Legt nach Folge den digitalen Ausgangszustand des pin des Booleschen val -Wahrheit oder ungleich Null als hoch, null oder sonst; kehrt nil zurück.
ana-r pin : Gibt einen analogen Eingangszustand des Pin-Number pin zurück.
ana-w [1-N pin val] pin val Legt nacheinander den Analog/PWM-Ausgangszustand des Pin- pin auf das 16-Bit-Integer val ; kehrt nil zurück.
ana-r pin : Gibt analog 16-Bit-Ganzzahleingang des Pin-Number- pin zurück.
Datei io verwandt
Hinweis: Auf Arduino -Dateien müssen nicht mehr als drei Zeichen.
file-r path : Gibt den Blob der gesamten Dateiinhalte zurück.
file-r path T : Gibt die Dateigröße zurück.
file-r path offset : Gibt den Blob von Dateiinhalten zwischen Offset-Bytes und EOF zurück.
file-r path offset count : Gibt den Blob von Dateiinhalten zwischen Offset und Up zu Bytes zurück.
Alle kehren nach Scheitern zurück.
file-a path content : Fängt einen Blob oder Element als Zeichenfolge an die Datei an.
file-w path content[ offset] : schreibt einen Blob oder Element als Zeichenfolge in eine Datei, optional mit einem Byte-Offset (ansonsten 0); Gibt den Erfolg als Boolean zurück.
Beide erwidern Erfolg als Boolean.
Hinweis: Saiten werden ohne Null -Terminator geschrieben.
file-d path : Löschung Datei am path ; Gibt den Erfolg als Boolean zurück.
Typen und Casting
type i : Gibt den Typ Code von Element i zurück.
type ab : Gibt den Typ -Code von Elementen a & b zurück, wenn sie gleich sind, ansonsten nil .
cast it : Gibt den Artikel zurück, den i als Typ Code t gegessen habe.
HINWEIS: Breiter bis dünner wird verkürzt, dünner bis breiter wird herausgezogen.
String to Blob fehlt die Null -Kündigung; Die Abgüsse zu Saiten werden mit Null -Kündigung angehängt.
Iteration
reduce f[ s*N] i : Rendite die Reduktion von Vektor oder String i durch f mit 0-N-Samen zurück. f ist (item acc) => acc .
map fv*N : Gibt die Zuordnung von 1-n-Vektoren über f zurück, wobei f (item*N) => mapped ist.
Beispiel: (map str [a b c] [1 2 3]) => [a1 b2 c3]
for fv*N : Gibt die iterative Zuordnung von 1-n-Vektoren durch f zurück, wobei f ist (item*N) => mapped .
Beispiel: (for str [a b c] [1 2 3]) => [a1 a2 a3 b1 b2 b3 c1 c2 c3]
loop nf : Wiederholt n 16-Bit Häufigkeit der Funktion f , wobei f ist (0…n) => any ; Rückgabe der letzten Rückkehr von f .
loop seed nf : Wie oben, aber f ist (acc 0…n) => any , wo acc zuerst seed ist, dann die Rückkehr der vorherigen Iteration.
loop seed abf : Wie oben, außer n reicht von a bis b .
Beispiel: (loop 2 {print "hello" #}) Drucke "Hello0" und "Hello1", kehrt Nil zurück.
Beispiel: (loop 0 5 +) => 10 .
Beispiel: (loop 0 5 10 +) => 35
Nachrichtenbezogen
Die Themen sind vorwärtsgerichtete Saiten ( / ). UN- /Abonnement -Themen verwenden die Wildcards /+/ für eine beliebige und /# für jedes Jenseits .
Beispiel: Das Thema house/kitchen/fridge entspricht dem Subcription house/+/fridge oder house/# oder +/kitchen/+ oder # , jedoch nicht garage/# oder house/bedroom/fridge oder house/+/sink .
pub topic[ payload] : Senden Sie eine Nachricht im gesamten VM mit dem topic String -Thema und optional eine payload (ansonsten Null) jeglicher Art.
Gibt NIL zurück oder wenn die Nachricht ein anderes Programm veröffentlichen, um eine Nachricht zu veröffentlichen, die das ursprüngliche Veröffentlichungsprogramm abonniert wurde,
Gibt den vom Originalverlagungsprogramm zurückgegebenen Staat zurück.
Hinweis: Die Veröffentlichung ist sofort und synchron - Ihr Programm muss warten, wenn Abonnenten die Nachricht verarbeiten.
sub topic f[ provide-topic] : Abonnieren Sie die Funktion f mit einem topic ,
wobei wenn provide-topic wahr ist, f (state topic payload) => new-state ,
sonst (Standard) f ist (state payload) => new-state ; kehrt nil zurück.
Hinweis: Nur Programmfunktionen werden als f - zur Verwendung einer nativen Operation verwendet, um eine Inline -Funktion zu verwenden.
unsub topic : Entfernen Sie das vorherige Abonnement des topic ; kehrt nil zurück.
unsub : Alle Programmabonnements fallen lassen; kehrt nil zurück.
System- und Programmbezogener
ms-now : Gibt Millisekunden seit der CHVM-Initialisierung zurück.
sleep ms : Verschiebt den nächsten Herzschlag des Programms für ms Miliseconds; kehrt nil zurück.
print 0-N Arg: Drucke Ergebnis von str von n Args; kehrt nil zurück.
load path : lädt das kompilierte Chika -Programm bei path (ohne Dateierweiterung); Gibt den Erfolg beim Laden des Programms zurück.
comp path-in[ path-out] : Kompiliert eine Quelldatei (idiomatisch *.chi ) bei path-in als Chika-Binär, entweder auf demselben Pfad mit der erweiterten Erweiterung in .kua oder bei path-out (idiomatisch *.kua ).
halt : Beendet das Chika -Programm sofort.
Eine kompilierte Chika -Binärin besteht aus nur aus Funktionen . Funktionen enthalten Formen . Formulare enthalten Argumente (die auch Formulare sein können) und enden mit einer Operation . Die hexadezimalen Byteformate sind:
Funktion
NNNNLLLL…
NNNN , uint16_t Incrementing -Funktions -ID; LLLL , uint16_t Funktion Körperlänge; … , LLLL -Länge Funktionskörper.
bilden
00…args…OO
00 , Formmarker; [args] , 0-n Args; OO eine Operation.
arg
oder 00… , eine Form
AA , uint8_t arg-code; … Variable-Größe maßgeschneiderte Argumentation.
Betrieb
OO
OO , uint8_t op-code.
00 FRM -Form
Todo
Todo