diff options
| author | Bruce Hill <bitbucket@bruce-hill.com> | 2018-06-12 15:12:27 -0700 |
|---|---|---|
| committer | Bruce Hill <bitbucket@bruce-hill.com> | 2018-06-12 15:14:07 -0700 |
| commit | b5fb8933af283d2b873a03ded085e8b69f374e81 (patch) | |
| tree | 5cf00c528eb339d5a9f4491652f8a9a0601d943b /nomsu_tree.moon | |
| parent | 0c9973ff0363e400d3d284339b77197c40c3f60c (diff) | |
Removed dependency on 'immutable' library. This lets LuaJIT do more
aggressive optimizations and generally helps performance. Some safety is
lost, but I think the performance gains, reduced complexity, and reduced
dependencies are worth it.
Diffstat (limited to 'nomsu_tree.moon')
| -rw-r--r-- | nomsu_tree.moon | 96 |
1 files changed, 40 insertions, 56 deletions
diff --git a/nomsu_tree.moon b/nomsu_tree.moon index 3339606..fe1c4f4 100644 --- a/nomsu_tree.moon +++ b/nomsu_tree.moon @@ -1,69 +1,53 @@ -- This file contains the datastructures used to represent parsed Nomsu syntax trees, -- as well as the logic for converting them to Lua code. -utils = require 'utils' -{:repr, :stringify, :min, :max, :equivalent, :set, :is_list, :sum} = utils -immutable = require 'immutable' +{:repr} = require 'utils' {:insert, :remove, :concat} = table -{:Lua, :Nomsu, :Source} = require "code_obj" +{:Source} = require "code_obj" -MAX_LINE = 80 -- For beautification purposes, try not to make lines much longer than this value - -Types = {} -Types.is_node = (n)-> - type(n) == 'userdata' and getmetatable(n) and Types[n.type] == getmetatable(n) +AST = {} +AST.is_syntax_tree = (n)-> + type(n) == 'table' and getmetatable(n) and AST[n.type] == getmetatable(n) -- Helper method: -Tree = (name, fields, methods)-> - methods or= {} - is_multi = true - for f in *fields do is_multi and= (f != "value") - with methods +Tree = (name, leaf_or_branch, methods)-> + cls = methods or {} + is_multi = leaf_or_branch == 'branch' + with cls .type = name - .name = name - .__new or= (source, ...)=> - assert source + .is_instance = (x)=> getmetatable(x) == @ + .__index = cls + .__tostring = => "#{@name}(#{@value and repr(@value) or table.concat([repr(v) for v in *@]), ', '})" + .map = (fn)=> + if replacement = fn(@) then return replacement + if @value then return @ + new_vals = [v.map and v\map(fn) or v for v in *@] + return getmetatable(self)(@source, unpack(new_vals)) + + AST[name] = setmetatable cls, + __tostring: => @name + __call: (source, ...)=> if type(source) == 'string' source = Source\from_string(source) - --assert Source\is_instance(source) - return source, ... - .is_multi = is_multi - if is_multi - .__tostring = => "#{@name}(#{table.concat [repr(v) for v in *@], ', '})" - .map = (fn)=> - if replacement = fn(@) - return replacement - new_vals = [v.map and v\map(fn) or v for v in *@] - return getmetatable(self)(@source, unpack(new_vals)) - else - .__tostring = => "#{@name}(#{repr(@value)})" - .map = (fn)=> - fn(@) or @ - - Types[name] = immutable fields, methods - -Tree "Block", {"source"} -Tree "EscapedNomsu", {"source"} -Tree "Text", {"source"} -Tree "List", {"source"} -Tree "Dict", {"source"} -Tree "DictEntry", {"source"} -Tree "IndexChain", {"source"} -Tree "Number", {"source", "value"} -Tree "Var", {"source", "value"} + assert(Source\is_instance(source)) + inst = if is_multi then {:source, ...} else {:source, value:...} + setmetatable(inst, @) + if inst.__init then inst\__init! + return inst -Tree "Action", {"source", "stub"}, - __new: (source, ...)=> - assert source - if type(source) == 'string' - source = Source\from_string(source) - --assert Source\is_instance(source) - stub_bits = {} - for i=1,select("#",...) - a = select(i, ...) - stub_bits[i] = type(a) == 'string' and a or "%" - stub = concat stub_bits, " " - return source, stub, ... +Tree "Number", 'leaf' +Tree "Var", 'leaf' +Tree "Block", 'branch' +Tree "EscapedNomsu", 'branch' +Tree "Text", 'branch' +Tree "List", 'branch' +Tree "Dict", 'branch' +Tree "DictEntry", 'branch' +Tree "IndexChain", 'branch' +Tree "Action", 'branch', + __init: => + stub_bits = [type(a) == 'string' and a or '%' for a in *@] + @stub = concat stub_bits, " " get_spec: => concat [type(a) == "string" and a or "%#{a.value}" for a in *@], " " -return Types +return AST |
