require "lib/metaprogramming.nom" # Error functions rule [error!, panic!, fail!, abort!] =: nomsu "error" [] rule [error %msg] =: nomsu "error"[%msg] compile [assert %condition %msg] to code: ".." if not (\(%condition as lua)) then nomsu:error(\(%msg as lua)); end parse [assert %condition] as: assert %condition (nil) # Text functions rule [join %strs with glue %glue] =: lua do> ".." local str_bits = {} for i,bit in ipairs(\%strs) do str_bits[i] = nomsu:stringify(bit) end return table.concat(str_bits, \%glue) parse [join %strs] as: join %strs with glue "" compile [capitalize %str, %str capitalized] to: "(\(%str as lua)):gsub('%l', string.upper, 1)" compile [%str with %patt replaced with %sub, %str s/%patt/%sub] to: "((\(%str as lua)):gsub(\(%patt as lua), \(%sub as lua)))" compile [%str with %patt replaced with %sub %n times, %str s/%patt/%sub/%n] to: "((\(%str as lua)):gsub(\(%patt as lua), \(%sub as lua), \(%n as lua)))" # Number ranges compile [%start to %stop by %step, %start to %stop via %step] to: ".." nomsu.utils.range(\(%start as lua), \(%stop as lua), \(%step as lua)) parse [%start to %stop] as: %start to %stop by 1 # Random functions lua> ".." # Seed math.randomseed(os.time()); for i=1,20 do; math.random(); end; compile [random number, random, rand] to: "math.random()" compile [random int %n, random integer %n, randint %n] to: "math.random(\(%n as lua))" compile [random from %low to %high, random number from %low to %high, rand %low %high] to: "math.random(\(%low as lua), \(%high as lua))" rule [random choice from %elements, random choice %elements, random %elements] =: =lua "\%elements[math.random(#\%elements)]" # Math functions compile [% as number] to: "tonumber(\(% as lua))" compile [abs %, absolute value of %, | % |] to: "math.abs(\(% as lua))" compile [sqrt %, square root of %] to: "math.sqrt(\(% as lua))" compile [sin %, sine %] to: "math.sin(\(% as lua))" compile [cos %, cosine %] to: "math.cos(\(% as lua))" compile [tan %, tangent %] to: "math.tan(\(% as lua))" compile [asin %, arc sine %] to: "math.asin(\(% as lua))" compile [acos %, arc cosine %] to: "math.acos(\(% as lua))" compile [atan %, arc tangent %] to: "math.atan(\(% as lua))" compile [atan2 %y %x] to: "math.atan2(\(%y as lua), \(%x as lua))" compile [sinh %, hyperbolic sine %] to: "math.sinh(\(% as lua))" compile [cosh %, hyperbolic cosine %] to: "math.cosh(\(% as lua))" compile [tanh %, hyperbolic tangent %] to: "math.tanh(\(% as lua))" compile [ceil %, ceiling %] to: "math.ceil(\(% as lua))" compile [exp %, e^ %] to: "math.exp(\(% as lua))" compile [log %, ln %, natural log %] to: "math.log(\(% as lua))" compile [log % base %base] to: "math.log(\(% as lua), \(%base as lua))" compile [floor %] to: "math.floor(\(% as lua))" compile [round %, % rounded] to: "math.floor(\(% as lua) + .5)" rule [%n rounded to the nearest %rounder] =: =lua "(\%rounder)*math.floor((\%n / \%rounder) + .5)" compile [tau] to: "(2*math.pi)" compile [pi] to: "math.pi" compile [e] to: "math.e" compile [golden ratio, phi] to: "((1 + math.sqrt(5)) / 2)" # Common utility functions rule [avg of %items, average of %items] =: =lua "(nomsu.utils.sum(\%items)/#\%items)" compile [min of %items, smallest of %items, lowest of %items] to: "nomsu.utils.min(\(%items as lua))" compile [max of %items, biggest of %items, largest of %items, highest of %items] to: "nomsu.utils.max(\(%items as lua))" compile [min of %items by %value_expr] to: ".." nomsu.utils.min(\(%items as lua), function(\(\% as lua)) return \(%value_expr as lua) end) compile [max of %items by %value_expr] to: ".." nomsu.utils.max(\(%items as lua), function(\(\% as lua)) return \(%value_expr as lua) end) compile [sort %items] to: "table.sort(\(%items as lua))" compile [sort %items by %key_expr] to: ".." nomsu.utils.sort(\(%items as lua), function(\(\% as lua)) return \(%key_expr as lua); end) # Text utilities compile [nl, newline, line feed, linefeed, lf] to: "'\\n'" compile [tab] to: "'\\t'" compile [bell] to: "'\\a'" compile [cr, carriage return] to: "'\\r'" compile [backspace] to: "'\\b'" compile [form feed, formfeed] to: "'\\f'" compile [vertical tab] to: "'\\v'" lua> ".." do local colors = { ["reset color"] = 0, bright = 1, dim = 2, underscore = 4, blink = 5, inverse = 7, hidden = 8, black = 30, red = 31, green = 32, yellow = 33, blue = 34, magenta = 35, cyan = 36, white = 37, ["on black"] = 40, ["on red"] = 41, ["on green"] = 42, ["on yellow"] = 43, ["on blue"] = 44, ["on magenta"] = 45, ["on cyan"] = 46, ["on white"] = 47, }; for name,code in pairs(colors) do local escape = "\\"\\\\27["..tostring(code).."m\\"" nomsu:defmacro(name, \(__line_no__), function() return escape end, ""); end end