aichaos / rivescript-go

A RiveScript interpreter for Go. RiveScript is a scripting language for chatterbots.
https://www.rivescript.com/
MIT License
60 stars 16 forks source link

Code Restructure #7

Closed kirsle closed 7 years ago

kirsle commented 7 years ago

This change restructures the source code to the Go RiveScript library to make a few useful things exported and to clean up clutter from the root of the git repo.

Reasons for the Refactor

The import path to the JavaScript macro handler has changed to a better name:

- import "github.com/aichaos/rivescript-go/lang/rivescript_js"
+ import "github.com/aichaos/rivescript-go/lang/javascript"

The correct import path now is github.com/aichaos/rivescript-go/lang/javascript for the JavaScript handler.

The Parser and AST

I wanted to make the RiveScript parser exported as its own stand-alone Go package, and I succeeded: github.com/aichaos/rivescript-go/parser

This required renaming the internal data structures for the Abstract Syntax Tree (AST), so that all of the AST types are exported so that they're useful to the parser package.

Previously, the AST types all had lowercased (non-exported) names, for my own sanity, so I don't have to keep track of when to use capital letters and when not to. I created the file src/astmap.go for internal use of the AST; it has all the same types as the exported AST except with private names, and the parser code in the main RiveScript package translates data from the exported AST to the private one. I'll let the docs in astmap.go speak for themselves:

For my own sanity while programming the code, these structs mirror the data in the 'ast' subpackage but uses non-exported fields for the bot's own use.

The logic is as follows:

  • The parser subpackage becomes a stand-alone Go module that third party developers can use to make their own applications around the RiveScript scripting language itself. To that end, it exports a public AST tree.
  • In RiveScript's parse() function, it uses the public parser package and gets back an AST tree full of exported fields. It doesn't need these fields to be exported, and it copies them into internal fields of similar names.
  • I don't want to use the exported AST names directly because it makes the code become a Russian Roulette of capital or non-capital names.

An example of how unwieldy the code would be if I use the direct AST types:

rs.thats[topic].Triggers[trigger.Trigger].Previous[trigger.Previous]
//              ^                ^        ^                ^

If the ast package structs are updated, update the mappings in this package too.

Changes

  • Moved the bulk of the RiveScript implementation code into the src/ subpackage, and in its old place created a very light wrapper around the implementation.
  • The src/ package still exports all the same stuff, but with big warnings to devs not to use the src package directly. (It has to export everything or else the wrapper couldn't work right).
  • The wrapper package becomes the Source of Truth for the public/official API and documentation.
  • The package path to the JavaScript handler is changed as above.
  • Added public facing external packages for the parser, AST, and object macro interface.
  • Added Changes.md to keep track of change notifications.