12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121 |
- // raku
- /* Raku is an easy to use scripting language that can also be used easily interactively
- Desired simplified syntax:
- PROGRAM -> STATEMENTS.
- STATEMENTS -> STATEMENT STATEMENTS | .
- STATEMENT -> EXPRESSION eox | BLOCK .
- EXPRESSION -> word PARAMETERS.
- PARAMETERS -> PARAMETER PARAMETERS | .
- PARAMETER -> word | VALUE | PARENTHESIS | BLOCK | operator.
- PARENTHESIS -> bep PARAMETER eop .
- BLOCK -> bob STATEMENTS eob .
- VALUE -> string | long | double | symbol.
- Desrired syntax (verified LL(1) on smlweb.cpsc.ucalgary.ca)
- PROGRAM -> STATEMENTS.
- STATEMENTS -> STATEMENT STATEMENTS | .
- STATEMENT -> EXPRESSION EOX | DEFINITION | BLOCK .
- DEFINITION -> define WORDOP WORDOPS BLOCK.
- WORDOPS -> WORDOP WORDOPS | .
- EXPRESSION -> WORDVALUE PARAMETERS.
- PARAMETERS -> PARAMETER PARAMETERS | .
- PARAMETER -> WORDVALUE | PARENTHESIS | BLOCK | operator.
- PARENTHESIS -> '(' EXPRESSION ')' | ot EXPRESSION ct.
- BLOCK -> oe STATEMENTS ce | do STATEMENTS end .
- WORDOP -> word | operator | a | the.
- WORDVALUE -> word | VALUE | a | the.
- VALUE -> string | number | symbol.
- EOX -> eol | period.
- Lexer:
- Yet another syntax, which supports operators, but requires () to use them,
- and [ ] to indicate expressions inside expressions.
- PROGRAM -> STATEMENTS.
- STATEMENTS -> STATEMENT STATEMENTS | .
- STATEMENT ->
- EXPRESSION EOX
- | BLOCK .
- EXPRESSION ->
- CALL
- | PARENTHESIS
- | RECTANGLE
- .
- CALL -> WORD PARAMETERS .
- RECTANGLE -> '[' EXPRESSION ']' |
- with EXPRESSION end .
- PARENTHESIS -> '(' OPERATION ')'
- | let OPERATION end .
- OPERATION -> PARAMETER OPLIST .
- OPLIST -> op OPLIST | .
- OP -> operator PARAMETER .
- PARAMETERS -> PARAMETER PARAMETERS | .
- PARAMETER -> WORDVALUE | BLOCK |
- PARENTHESIS | RECTANGLE .
- BLOCK -> '{' STATEMENTS '}' | do STATEMENTS end .
- WORDVALUE -> word | VALUE | a | the.
- VALUE -> string | number | symbol.
- EOX -> '\n' .
- Most simple "lisp but with less parenthesis" syntax:
- PROGRAM -> STATEMENTS.
- STATEMENTS -> STATEMENT STATEMENTS | .
- STATEMENT -> CALL | EOX | BLOCK .
- BLOCK -> '{' STATEMENTS '}' .
- CALL -> word PARAMETERS EOX .
- PARAMETERS -> PARAMETER PARAMETERS | .
- PARAMETER -> WORDVALUE | BLOCK .
- WORDVALUE -> word | VALUE .
- VALUE -> string | number | symbol.
- EOX -> '\n' .
- LMore TCL-is allows operators in () and forces evaluation of blocks in [].
- PROGRAM -> STATEMENTS.
- STATEMENTS -> STATEMENT STATEMENTS | .
- STATEMENT ->
- COMMAND
- | SUBSTITUTION
- | BLOCK
- | EXPRESSION
- | EOX
- .
- BLOCK ->
- '{' STATEMENTS '}'
- | do STATEMENTS end .
- SUBSTITUTION ->
- '[' STATEMENTS ']'
- | evaluate STATEMENTS end .
- EXPRESSION ->
- '(' EXPRBODY ')'
- | calculate EXPRBODY end .
- EXPRBODY -> OPERAND OPERANDS.
- OPERANDS -> operator OPERANDS | .
- OPERAND -> PARAMETER .
- COMMAND -> word PARAMETERS EOX .
- ARGUMENTS -> WORDVALUE ARGUMENTS | .
- PARAMETERS -> PARAMETER PARAMETERS | .
- PARAMETER -> WORDVALUE | SUBSTITUTION | EXPRESSION | BLOCK .
- WORDVALUE -> word | VALUE .
- VALUE -> string | number | symbol | true | false | nothing .
- EOX -> '\n' .
- set (door's state) to closed .
- # Type a grammar here:
- PROGRAM -> STATEMENTS.
- STATEMENTS -> STATEMENT STATEMENTS | .
- STATEMENT ->
- COMMAND
- | SUBSTITUTION
- | BLOCK
- | EXPRESSION
- | EOX
- .
- BLOCK ->
- '{' STATEMENTS '}'
- | do STATEMENTS end .
- SUBSTITUTION ->
- '[' STATEMENTS ']'
- | evaluate STATEMENTS end .
- EXPRESSION ->
- '(' EXPRBODY ')'
- | calculate EXPRBODY end .
- EXPRBODY -> OPERAND OPERANDS.
- OPERANDS -> operator OPERANDS | .
- OPERAND -> PARAMETER .
- COMMAND -> word PARAMETERS EOX .
- ARGUMENTS -> WORDVALUE ARGUMENTS | .
- PARAMETERS -> PARAMETER PARAMETERS | .
- PARAMETER -> WORDVALUE | SUBSTITUTION | EXPRESSION | BLOCK .
- WORDVALUE -> word | VALUE .
- VALUE -> string | number | symbol | true | false | nothing .
- EOX -> '\n' .
- # Or, this gramar, also useful as a generic command parser for
- # AIF or MUx itself. Though necessarily more complex .
- PROGRAM -> STATEMENTS.
- STATEMENTS -> STATEMENT STATEMENTS | .
- STATEMENT ->
- COMMAND
- | SUBSTITUTION
- | BLOCK
- | EXPRESSION
- | EOX
- .
- BLOCK ->
- '{' STATEMENTS '}'
- | do STATEMENTS end .
- SUBSTITUTION ->
- '[' STATEMENTS ']'
- | evaluate STATEMENTS end .
- EXPRESSION ->
- '(' EXPRBODY ')'
- | calculate EXPRBODY end .
- EXPRBODY -> OPERAND OPERANDS.
- OPERANDS -> operator OPERANDS | .
- OPERAND -> PARAMETER .
- COMMAND -> word ARGUMENTS EOX .
- ARGUMENTS -> ARGUMENT ARGUMENT_SEP ARGUMENTS | .
- ARGUMENT_SEP -> ',' | preposition | article | .
- ARGUMENT -> LITERAL | SUBSTITUTION | EXPRESSION | BLOCK .
- WORDLIT -> word | LITERAL .
- LITERAL -> string | number | symbol | true | false | nothing .
- EOX -> '\n' .
- type Duration (is a) number
- ( also could say a Duration (is a) number )
- type Effect (is an) integer
- constant No Effect is 1
- constant Healing Effect is an Effect which is 1
- the Damaging Effect is an Effect which is 2
- ( the is another way to say constant / variable )
- type Spell (is a) record (which) has
- (a) name (which is a/as a) String
- (a) Duration
- (an) Effect
- end
- variable cure light is a Spell which has
- name is "Cure Light"
- Duration is Duration 0.0
- Effect is Healing Effect
- end
- ( could have been the cure light is a spell ... )
- to cast (a) Spell at (a) Being do
- ( ... )
- end
- to cast (a) s which is a Spell at (a) b which is a Being do
- ( ... )
- end
- to add n1 which is a Number to n2 which is a Number do
- end
- to add one Number to another Number do
- one becomes one plus another
- end
- to duck do
- let text be "You duck"
- one becomes one plus another
- end
- type spellike (is an) interface which has
- cast (a) at Being
- end
- type Spell aliases spell
- cast cure light at Ben
- English single word prepositions :
- in
- aboard
- about
- above
- absent
- across
- after
- against
- along
- alongside
- amid
- amidst
- among
- apropos
- apud
- around
- as
- astride
- at
- on
- atop
- ontop
- bar
- before
- behind
- below
- beneath
- beside
- besides
- between
- beyond
- but
- by
- chez
- circa
- come
- dehors
- despite
- down
- during
- except
- for
- from
- in
- inside
- into
- less
- like
- minus
- near
- nearer
- nearest
- notwithstanding
- of
- off
- on
- onto
- opposite
- out
- outside
- over
- pace
- past
- per
- post
- pre
- pro
- qua
- re
- sans
- save
- short
- since
- than
- through
- thru
- throughout
- to
- toward
- towards
- under
- underneath
- unlike
- until
- up
- upon
- upside
- versus
- via
- vice
- vis-à-vis
- with
- within
- without
- worth
- */
- package raku
- import (
- "bytes"
- "errors"
- "fmt"
- "io"
- "reflect"
- "runtime"
- "strings"
- "unicode"
- // "gitlab.com/beoran/woe/graphviz"
- "gitlab.com/beoran/woe/monolog"
- "gitlab.com/beoran/woe/tree"
- )
- type TokenChannel chan *Token
- type Lexer struct {
- Reader io.Reader
- Positions []Position
- Token Token
- rule LexerRule
- Output TokenChannel
- buffer []byte
- runes []rune
- }
- type LexerRule func(lexer *Lexer) LexerRule
- func (me *Lexer) Last() Position {
- return me.Positions[1]
- }
- func (me *Lexer) Current() Position {
- return me.Positions[0]
- }
- func (me *Lexer) LastPtr() * Position {
- return &me.Positions[1]
- }
- func (me *Lexer) CurrentPtr() * Position {
- return &me.Positions[0]
- }
- func (me *Lexer) PushPosition(pos Position) {
- newpos := make([]Position, len(me.Positions) + 1)
- newpos[0] = pos
- for i := 1 ; i < len(me.Positions); i++ {
- newpos[i] = me.Positions[i-1]
- }
- me.Positions = newpos
- }
- func (me *Lexer) PushCurrentPosition() {
- current := me.Current()
- me.PushPosition(current)
- }
- func (me *Lexer) PopPosition() * Position {
- if (len(me.Positions) <= 2) {
- return nil
- }
-
- result := &me.Positions[0];
- newpos := make([]Position, len(me.Positions) - 1)
- for i := 1 ; i < len(me.Positions); i++ {
- newpos[i-1] = me.Positions[i]
- }
- me.Positions = newpos
- return result
- }
- func (me *Lexer) Emit(t TokenType, v TokenText) {
- tok := &Token{t, v, me.Current()}
- me.Output <- tok
- }
- func (me *Lexer) Error(message string, args ...interface{}) {
- value := fmt.Sprintf(message, args...)
- monolog.Error("Lex Error: %s", value)
- me.Emit(TokenError, TokenText(value))
- }
- func LexError(me *Lexer) LexerRule {
- me.Error("Error")
- return nil
- }
- func (me *Lexer) SkipComment() bool {
- if me.Peek() == '#' {
- if me.Next() == '(' {
- return me.SkipNotIn(")")
- } else {
- return me.SkipNotIn("\r\n")
- }
- }
- return true
- }
- /* Returns whether or not a keyword was found, and if so, the TokenType
- of the keyword.*/
- func LookupKeyword(word string) (bool, TokenType) {
- kind, found := keywordMap[word]
- return found, kind
- }
- /* Returns whether or not a special operator or sigil was found, and if so,
- returns the TokenTyp of the sigil.*/
- func LookupSigil(sigil string) (bool, TokenType) {
- fmt.Printf("LookupSigil: %s\n", sigil)
- kind, found := sigilMap[sigil]
- return found, kind
- }
- func LexSigil(me *Lexer) LexerRule {
- me.Found(TokenType(me.Peek()))
- _ = me.Next()
- me.Advance()
- return LexNormal
- }
- func LexWord(me *Lexer) LexerRule {
- me.SkipNotIn(" \t\r\n'({[]})")
- iskw, kind := LookupKeyword(me.CurrentStringValue())
- if iskw {
- me.Found(kind)
- } else {
- me.Found(TokenWord)
- }
- return LexNormal
- }
- func LexSymbol(me *Lexer) LexerRule {
- me.SkipNotIn(" \t\r\n'({[]})")
- me.Found(TokenSymbol)
- return LexNormal
- }
- func LexNumber(me *Lexer) LexerRule {
- me.SkipNotIn(" \t\r\n'({[]})")
- me.Found(TokenNumber)
- return LexNormal
- }
- func LexWhitespace(me *Lexer) LexerRule {
- me.SkipWhitespace()
- me.Advance()
- return LexNormal
- }
- func LexComment(me *Lexer) LexerRule {
- if !me.SkipComment() {
- me.Error("Unterminated comment")
- return LexError
- }
- me.Advance()
- return LexNormal
- }
- func LexPunctuator(me *Lexer) LexerRule {
- me.Found(TokenType(me.Peek()))
- _ = me.Next()
- me.Advance()
- return LexNormal
- }
- func LexEOL(me *Lexer) LexerRule {
- me.SkipIn("\r\n")
- me.Found(TokenEOL)
- return LexNormal
- }
- func LexOperator(me *Lexer) LexerRule {
- me.SkipIn(operator_chars)
- me.Found(TokenOperator)
- return LexNormal
- }
- func lexEscape(me *Lexer) error {
- _ = me.Next()
- return nil
- }
- func LexString(me *Lexer) LexerRule {
- open := me.Peek()
- do_escape := open == '"'
- peek := me.Next()
- me.Advance()
- for ; peek != '\000'; peek = me.Next() {
- if do_escape && peek == '\\' {
- if err := lexEscape(me); err != nil {
- return LexError
- }
- } else if peek == open {
- me.Found(TokenString)
- _ = me.Next()
- me.Advance()
- return LexNormal
- }
- }
- me.Error("Unexpected EOF in string.")
- return nil
- }
- func LexNumberOrOperator(me *Lexer) LexerRule {
- if unicode.IsDigit(me.Next()) {
- return LexNumber
- } else {
- _ = me.Previous()
- return LexOperator
- }
- }
- func LexNormal(me *Lexer) LexerRule {
- peek := me.Peek()
- if peek == '#' {
- return LexComment
- } else if strings.ContainsRune(" \t", peek) {
- return LexWhitespace
- } else if strings.ContainsRune(".,;:", peek) {
- return LexPunctuator
- } else if strings.ContainsRune("([{}])", peek) {
- return LexSigil
- } else if strings.ContainsRune("$", peek) {
- return LexSymbol
- } else if strings.ContainsRune("\r\n", peek) {
- return LexEOL
- } else if strings.ContainsRune("+-", peek) {
- return LexNumberOrOperator
- } else if strings.ContainsRune("\"`", peek) {
- return LexString
- } else if peek == '\000' {
- me.Emit(TokenEOF, "")
- return nil
- } else if unicode.IsLetter(peek) {
- return LexWord
- } else if unicode.IsDigit(peek) {
- return LexNumber
- } else if strings.ContainsRune(operator_chars, peek) {
- return LexOperator
- } else {
- return LexError
- }
- }
- func OpenLexer(reader io.Reader) *Lexer {
- lexer := &Lexer{}
- lexer.Reader = reader
- lexer.Output = make(TokenChannel)
- lexer.Positions = make([]Position, 2)
- // lexer.buffer = new(byte[1024])
- return lexer
- }
- func (me *Lexer) ReadReaderOnce() (bool, error) {
- buffer := make([]byte, 1024)
- n, err := me.Reader.Read(buffer)
- monolog.Debug("read %v %d %v\n", buffer[:n], n, err)
- if n > 0 {
- me.buffer = append(me.buffer, buffer[:n]...)
- monolog.Debug("append %s", me.buffer)
- }
- if err == io.EOF {
- return true, nil
- } else if err != nil {
- me.Error("Error reading from reader: %s", err)
- return true, err
- }
- return false, nil
- }
- func (me *Lexer) ReadReader() error {
- me.buffer = make([]byte, 0)
- more, err := me.ReadReaderOnce()
- for err == nil && more {
- more, err = me.ReadReaderOnce()
- }
- me.runes = bytes.Runes(me.buffer)
- return err
- }
- func (me *Lexer) Peek() rune {
- if (me.Current().Index) >= len(me.runes) {
- return '\000'
- }
- return me.runes[me.Current().Index]
- }
- func (me *Lexer) PeekNext() rune {
- if (me.Current().Index + 1) >= len(me.runes) {
- return '\000'
- }
- return me.runes[me.Current().Index+1]
- }
- func (me *Lexer) Next() rune {
- if me.Peek() == '\n' {
- me.CurrentPtr().Column = 0
- me.CurrentPtr().Row++
- }
- me.CurrentPtr().Index++
- if me.Current().Index >= len(me.runes) {
- //me.Emit(TokenEOF, "")
- }
- return me.Peek()
- }
- func (me *Lexer) Previous() rune {
- if me.Current().Index > 0 {
- me.CurrentPtr().Index--
- if me.Peek() == '\n' {
- me.CurrentPtr().Column = 0
- me.CurrentPtr().Row++
- }
- }
- return me.Peek()
- }
- func (me *Lexer) SkipRune() {
- _ = me.Next()
- }
- func (me *Lexer) SkipIn(set string) bool {
- for strings.ContainsRune(set, me.Next()) {
- monolog.Debug("SkipIn: %s %c\n", set, me.Peek())
- if me.Peek() == '\000' {
- return false
- }
- }
- return true
- }
- func (me *Lexer) SkipNotIn(set string) bool {
- _ = me.Next()
- for !strings.ContainsRune(set, me.Peek()) {
- if me.Next() == '\000' {
- return false
- }
- }
- return true
- }
- func (me *Lexer) SkipWhile(should_skip func(r rune) bool) bool {
- for should_skip(me.Peek()) {
- if me.Next() == '\000' {
- return false
- }
- }
- return true
- }
- func (me *Lexer) SkipWhitespace() {
- me.SkipIn(" \t")
- }
- func (me *Lexer) Advance() {
- (*me.LastPtr()) = me.Current()
- }
- func (me *Lexer) Rewind() {
- (*me.CurrentPtr()) = me.Last()
- }
- func (me *Lexer) CurrentRuneValue() []rune {
- return me.runes[me.Last().Index:me.Current().Index]
- }
- func (me *Lexer) CurrentStringValue() string {
- return string(me.CurrentRuneValue())
- }
- func (me *Lexer) Found(kind TokenType) {
- me.Emit(kind, TokenText(me.CurrentStringValue()))
- me.Advance()
- }
- func GetFunctionName(fun interface{}) string {
- return runtime.FuncForPC(reflect.ValueOf(fun).Pointer()).Name()
- }
- func (me *Lexer) Start() {
- if err := me.ReadReader(); err == nil || err == io.EOF {
- rule := LexNormal
- for rule != nil {
- monolog.Debug("Lexer Rule: %s\n", GetFunctionName(rule))
- rule = rule(me)
- }
- } else {
- me.Error("Could not read in input buffer: %s", err)
- }
- close(me.Output)
- }
- func (me *Lexer) TryLexing() {
- go me.Start()
- for token := range me.Output {
- monolog.Info("Token %s", token)
- }
- }
- type AstType int
- const (
- AstTypeProgram = AstType(iota)
- AstTypeStatements
- AstTypeStatement
- AstTypeDefinition
- AstTypeWords
- AstTypeExpression
- AstTypeWordExpression
- AstTypeWordCallop
- AstTypeOperation
- AstTypeOperations
- AstTypeCallArgs
- AstTypeValueExpression
- AstTypeValueCallop
- AstTypeParametersNonempty
- AstTypeParameters
- AstTypeParameter
- AstTypeBlock
- AstTypeWordValue
- AstTypeWord
- AstTypeValue
- AstTypeEox
- AstTypeOperator
- AstTypeParenthesis
- AstTypeModifier
- AstTypeError
- )
- var astTypeMap map[AstType]string = map[AstType]string{
- AstTypeProgram: "Program",
- AstTypeStatements: "Statements",
- AstTypeStatement: "Statement",
- AstTypeDefinition: "Definition",
- AstTypeWords: "Words",
- AstTypeExpression: "Expression",
- AstTypeWordExpression: "WordExpression",
- AstTypeWordCallop: "WordCallop",
- AstTypeOperation: "Operation",
- AstTypeOperations: "Operations",
- AstTypeCallArgs: "CallArgs",
- AstTypeValueExpression: "ValueExpression",
- AstTypeValueCallop: "ValueCallop",
- AstTypeParametersNonempty: "ParametersNonempty",
- AstTypeParameters: "Parameters",
- AstTypeParameter: "Parameter",
- AstTypeBlock: "Block",
- AstTypeWordValue: "WordValue",
- AstTypeWord: "Word",
- AstTypeValue: "Value",
- AstTypeEox: "Eox",
- AstTypeOperator: "Operator",
- AstTypeParenthesis: "Parenthesis",
- AstTypeModifier: "Modifier",
- AstTypeError: "Error",
- }
- func (me AstType) String() string {
- name, found := astTypeMap[me]
- if found {
- return name
- } else {
- return fmt.Sprintf("Unknown AstType %d", int(me))
- }
- }
- type Ast struct {
- tree.Node
- AstType
- *Token
- }
- func (me *Ast) Run(run *Runtime) (*Value, error) {
- switch me.AstType {
- case AstTypeProgram:
- return me.RunProgram(run)
- case AstTypeStatements:
- return me.RunStatements(run)
- case AstTypeStatement:
- return me.RunStatement(run)
- case AstTypeDefinition:
- return me.RunDefinition(run)
- case AstTypeWords:
- return me.RunWords(run)
- case AstTypeExpression:
- return me.RunExpression(run)
- case AstTypeWordExpression:
- return me.RunWord(run)
- case AstTypeWordCallop:
- return me.RunWordCallop(run)
- case AstTypeOperation:
- return me.RunOperation(run)
- case AstTypeOperations:
- return me.RunOperations(run)
- case AstTypeCallArgs:
- return me.RunCallArgs(run)
- case AstTypeValueExpression:
- return me.RunValueExpression(run)
- case AstTypeValueCallop:
- return me.RunValueCallop(run)
- case AstTypeParametersNonempty:
- return me.RunParametersNonempty(run)
- case AstTypeParameters:
- return me.RunParameters(run)
- case AstTypeParameter:
- return me.RunParameter(run)
- case AstTypeBlock:
- return me.RunBlock(run)
- case AstTypeWordValue:
- return me.RunWordValue(run)
- case AstTypeWord:
- return me.RunWord(run)
- case AstTypeValue:
- return me.RunValue(run)
- case AstTypeEox:
- return me.RunEox(run)
- case AstTypeOperator:
- return me.RunOperator(run)
- case AstTypeParenthesis:
- return me.RunParenthesis(run)
- case AstTypeModifier:
- return me.RunModifier(run)
- case AstTypeError:
- return me.RunError(run)
- default:
- return nil, errors.New("Shoudln't happen")
- }
- }
- func (me *Ast) RunProgram(run *Runtime) (*Value, error) {
- return nil, errors.New("Not implemented")
- }
- func (me *Ast) RunStatements(run *Runtime) (*Value, error) {
- return nil, errors.New("Not implemented")
- }
- func (me *Ast) RunStatement(run *Runtime) (*Value, error) {
- return nil, errors.New("Not implemented")
- }
- func (me *Ast) RunDefinition(run *Runtime) (*Value, error) {
- return nil, errors.New("Not implemented")
- }
- func (me *Ast) RunWords(run *Runtime) (*Value, error) {
- return nil, errors.New("Not implemented")
- }
- func (me *Ast) RunExpression(run *Runtime) (*Value, error) {
- return nil, errors.New("Not implemented")
- }
- func (me *Ast) RunWordExpression(run *Runtime) (*Value, error) {
- return nil, errors.New("Not implemented")
- }
- func (me *Ast) RunWordCallop(run *Runtime) (*Value, error) {
- return nil, errors.New("Not implemented")
- }
- func (me *Ast) RunOperation(run *Runtime) (*Value, error) {
- return nil, errors.New("Not implemented")
- }
- func (me *Ast) RunOperations(run *Runtime) (*Value, error) {
- return nil, errors.New("Not implemented")
- }
- func (me *Ast) RunCallArgs(run *Runtime) (*Value, error) {
- return nil, errors.New("Not implemented")
- }
- func (me *Ast) RunValueExpression(run *Runtime) (*Value, error) {
- return nil, errors.New("Not implemented")
- }
- func (me *Ast) RunValueCallop(run *Runtime) (*Value, error) {
- return nil, errors.New("Not implemented")
- }
- func (me *Ast) RunParametersNonempty(run *Runtime) (*Value, error) {
- return nil, errors.New("Not implemented")
- }
- func (me *Ast) RunParameters(run *Runtime) (*Value, error) {
- return nil, errors.New("Not implemented")
- }
- func (me *Ast) RunParameter(run *Runtime) (*Value, error) {
- return nil, errors.New("Not implemented")
- }
- func (me *Ast) RunBlock(run *Runtime) (*Value, error) {
- return nil, errors.New("Not implemented")
- }
- func (me *Ast) RunWordValue(run *Runtime) (*Value, error) {
- return nil, errors.New("Not implemented")
- }
- func (me *Ast) RunWord(run *Runtime) (*Value, error) {
- return nil, errors.New("Not implemented")
- }
- func (me *Ast) RunValue(run *Runtime) (*Value, error) {
- return nil, errors.New("Not implemented")
- }
- func (me *Ast) RunEox(run *Runtime) (*Value, error) {
- return nil, errors.New("Not implemented")
- }
- func (me *Ast) RunOperator(run *Runtime) (*Value, error) {
- return nil, errors.New("Not implemented")
- }
- func (me *Ast) RunParenthesis(run *Runtime) (*Value, error) {
- return nil, errors.New("Not implemented")
- }
- func (me *Ast) RunModifier(run *Runtime) (*Value, error) {
- return nil, errors.New("Not implemented")
- }
- func (me *Ast) RunError(run *Runtime) (*Value, error) {
- return nil, errors.New("Not implemented")
- }
- func (me *Ast) NewChild(kind AstType, token *Token) *Ast {
- child := &Ast{}
- child.AstType = kind
- child.Token = token
- tree.AppendChild(me, child)
- return child
- }
- func (me *Ast) Walk(walker func(ast *Ast) *Ast) *Ast {
- node_res := tree.Walk(me,
- func(node tree.Noder) tree.Noder {
- ast_res := walker(node.(*Ast))
- if ast_res == nil {
- return nil
- } else {
- return ast_res
- }
- })
- if node_res != nil {
- return node_res.(*Ast)
- } else {
- return nil
- }
- }
- func (me *Ast) Remove() {
- _ = tree.Remove(me)
- }
- func NewAst(kind AstType) *Ast {
- ast := &Ast{}
- ast.AstType = kind
- ast.Token = nil
- return ast
- }
- type DefineType int
- const (
- DefineTypeNone = DefineType(iota)
- DefineTypeGo
- DefineTypeUser
- DefineTypeVar
- )
- type Variable struct {
- Value
- Name string
- }
- type DefinePattern struct {
- Parts []string
- }
- type GoDefineFunc func(runtime *Runtime, args ...Value) Value
- type ScriptDefine struct {
- DefineType
- DefinePattern
- *Ast
- }
- type GoDefine struct {
- DefineType
- *DefinePattern
- GoDefineFunc
- }
- type Define interface {
- }
- type Environment struct {
- Parent *Environment
- Defines map[string]Define
- Variables map[string]*Variable
- Stack []Value
- }
- type Instruction int
- const (
- InstructionNop = Instruction(iota)
- InstructionCall
- InstructionPush
- InstructionPop
- )
- func (env *Environment) AddDefine(name string, def Define) {
- env.Defines[name] = def
- }
- func (env *Environment) NewGoDefine(name string, fn GoDefineFunc, pattern ...string) {
- defpattern := new(DefinePattern)
- defpattern.Parts = append(defpattern.Parts, pattern...)
- godefine := &GoDefine{DefineTypeGo, defpattern, fn}
- env.AddDefine(name, godefine)
- }
- type Runtime struct {
- Environment
- start *Ast
- now *Ast
- }
- func RuntimePuts(runtime *Runtime, args ...Value) Value {
- var iargs []interface{}
- for arg := range args {
- iargs = append(iargs, arg)
- }
- fmt.Print(iargs)
- return true
- }
- func (run *Runtime) Init() {
- run.NewGoDefine("puts", RuntimePuts, "$", "*")
- }
- func (run *Runtime) Start(ast *Ast) {
- run.start = ast
- run.now = ast
- }
- func (run *Runtime) RunOnce() {
- // run.now.Node
- }
- func main() {
- fmt.Println("Hello World!")
- }
|