123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137 |
- // 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 Value interface {
- }
- type StringValue string
- type SymbolValue string
- type IntegerValue int64
- type FloatValue float64
- type ArrayValue []Value
- type MapValue map[string]Value
- type BoolValue bool
- 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!")
- }
|