diff --git a/lexers/o/openscad.go b/lexers/o/openscad.go new file mode 100644 index 0000000..1215d7a --- /dev/null +++ b/lexers/o/openscad.go @@ -0,0 +1,43 @@ +package o + +import ( + . "github.com/alecthomas/chroma" // nolint + "github.com/alecthomas/chroma/lexers/internal" +) + +var OpenSCAD = internal.Register(MustNewLexer( + &Config{ + Name: "OpenSCAD", + Aliases: []string{"openscad"}, + Filenames: []string{"*.scad"}, + MimeTypes: []string{"text/x-scad"}, + }, + Rules{ + "root": { + {`[^\S\n]+`, Text, nil}, + {`\n`, Text, nil}, + {`//(\n|[\w\W]*?[^\\]\n)`, CommentSingle, nil}, + {`/(\\\n)?[*][\w\W]*?[*](\\\n)?/`, CommentMultiline, nil}, + {`/(\\\n)?[*][\w\W]*`, CommentMultiline, nil}, + {`[{}\[\]\(\),;:]`, Punctuation, nil}, + {`[*!#%\-+=?/]`, Operator, nil}, + {`<|<=|==|!=|>=|>|&&|\|\|`, Operator, nil}, + {`\$(f[asn]|t|vp[rtd]|children)`, NameVariableMagic, nil}, + {Words(``, `\b`, `PI`, `undef`), KeywordConstant, nil}, + {`(use|include)((?:\s|\\\\s)+)`, ByGroups(KeywordNamespace, Text), Push("includes")}, + {`(module)(\s*)([^\s\(]+)`, ByGroups(KeywordNamespace, Text, NameNamespace), nil}, + {`(function)(\s*)([^\s\(]+)`, ByGroups(KeywordDeclaration, Text, NameFunction), nil}, + {`\b(true|false)\b`, Literal, nil}, + {`\b(function|module|include|use|for|intersection_for|if|else|return)\b`, Keyword, nil}, + {`\b(circle|square|polygon|text|sphere|cube|cylinder|polyhedron|translate|rotate|scale|resize|mirror|multmatrix|color|offset|hull|minkowski|union|difference|intersection|abs|sign|sin|cos|tan|acos|asin|atan|atan2|floor|round|ceil|ln|log|pow|sqrt|exp|rands|min|max|concat|lookup|str|chr|search|version|version_num|norm|cross|parent_module|echo|import|import_dxf|dxf_linear_extrude|linear_extrude|rotate_extrude|surface|projection|render|dxf_cross|dxf_dim|let|assign|len)\b`, NameBuiltin, nil}, + {`\bchildren\b`, NameBuiltinPseudo, nil}, + {`"(\\\\|\\"|[^"])*"`, LiteralStringDouble, nil}, + {`-?\d+(\.\d+)?(e[+-]?\d+)?`, Number, nil}, + {`[a-zA-Z_]\w*`, Name, nil}, + }, + "includes": { + {"(<)([^>]*)(>)", ByGroups(Punctuation, CommentPreprocFile, Punctuation), nil}, + Default(Pop(1)), + }, + }, +)) diff --git a/lexers/testdata/openscad.actual b/lexers/testdata/openscad.actual new file mode 100644 index 0000000..7dc6e2a --- /dev/null +++ b/lexers/testdata/openscad.actual @@ -0,0 +1,46 @@ +use +include <../common/base.scad> + +/* + Multiline + Comment +*/ + +//draw a foobar +module foobar(){ + translate([0,-10,0]) + difference(){ + height=5+6; + cube([height,10.04,2.99e+8]); + sphere(r=PI,$fn=100); + } +} + +foobar(); +#cube ([5,5,5]); +echo("done"); + +function func0() = 5; +function func1(x=3) = 2*x+1; +function func2() = [1,2,3,4]; +function func3(y=7) = (y==7) ? 5 : 2 ; +function func4(p0,p1,p2,p3) = [p0,p1,p2,p3]; + +echo (func0()); // 5 +a = func1(); // 7 +b= func1(5); // 11 +echo (func2()); // [1, 2, 3, 4] +echo( func3(2),func3()); // 2, 5 + +z= func4(func0(),func1(),func2(),func3()); // [5, 7, [1, 2, 3, 4], 5] + +translate([0,-4*func0(),0])cube([func0(),2*func0(),func0()]); + +module parallelogram(x=1,y=1,angle=90) + {polygon([[0,0],[x,0], + [x+x*cos(angle)/sin(angle),y], + [x*cos(angle)/sin(angle),y]]);}; + +parallelogram(10,10,35); + + function add_up_to(n) = ( n==0 ? 0 : n + add_up_to(n-1) ); diff --git a/lexers/testdata/openscad.expected b/lexers/testdata/openscad.expected new file mode 100644 index 0000000..eda2a12 --- /dev/null +++ b/lexers/testdata/openscad.expected @@ -0,0 +1,367 @@ +[ + {"type":"KeywordNamespace","value":"use"}, + {"type":"Text","value":" "}, + {"type":"Punctuation","value":"\u003c"}, + {"type":"CommentPreprocFile","value":"write.scad"}, + {"type":"Punctuation","value":"\u003e"}, + {"type":"Text","value":"\n"}, + {"type":"KeywordNamespace","value":"include"}, + {"type":"Text","value":" "}, + {"type":"Punctuation","value":"\u003c"}, + {"type":"CommentPreprocFile","value":"../common/base.scad"}, + {"type":"Punctuation","value":"\u003e"}, + {"type":"Text","value":"\n\n"}, + {"type":"CommentMultiline","value":"/*\n\tMultiline\n\tComment\n*/"}, + {"type":"Text","value":"\n\n"}, + {"type":"CommentSingle","value":"//draw a foobar\n"}, + {"type":"KeywordNamespace","value":"module"}, + {"type":"Text","value":" "}, + {"type":"NameNamespace","value":"foobar"}, + {"type":"Punctuation","value":"(){"}, + {"type":"Text","value":"\n "}, + {"type":"NameBuiltin","value":"translate"}, + {"type":"Punctuation","value":"(["}, + {"type":"LiteralNumber","value":"0"}, + {"type":"Punctuation","value":","}, + {"type":"Operator","value":"-"}, + {"type":"LiteralNumber","value":"10"}, + {"type":"Punctuation","value":","}, + {"type":"LiteralNumber","value":"0"}, + {"type":"Punctuation","value":"])"}, + {"type":"Text","value":"\n "}, + {"type":"NameBuiltin","value":"difference"}, + {"type":"Punctuation","value":"(){"}, + {"type":"Text","value":"\n \t"}, + {"type":"Name","value":"height"}, + {"type":"Operator","value":"="}, + {"type":"LiteralNumber","value":"5"}, + {"type":"Operator","value":"+"}, + {"type":"LiteralNumber","value":"6"}, + {"type":"Punctuation","value":";"}, + {"type":"Text","value":"\n "}, + {"type":"NameBuiltin","value":"cube"}, + {"type":"Punctuation","value":"(["}, + {"type":"Name","value":"height"}, + {"type":"Punctuation","value":","}, + {"type":"LiteralNumber","value":"10.04"}, + {"type":"Punctuation","value":","}, + {"type":"LiteralNumber","value":"2.99e+8"}, + {"type":"Punctuation","value":"]);"}, + {"type":"Text","value":"\n "}, + {"type":"NameBuiltin","value":"sphere"}, + {"type":"Punctuation","value":"("}, + {"type":"Name","value":"r"}, + {"type":"Operator","value":"="}, + {"type":"KeywordConstant","value":"PI"}, + {"type":"Punctuation","value":","}, + {"type":"NameVariableMagic","value":"$fn"}, + {"type":"Operator","value":"="}, + {"type":"LiteralNumber","value":"100"}, + {"type":"Punctuation","value":");"}, + {"type":"Text","value":"\n "}, + {"type":"Punctuation","value":"}"}, + {"type":"Text","value":"\n"}, + {"type":"Punctuation","value":"}"}, + {"type":"Text","value":"\n\n"}, + {"type":"Name","value":"foobar"}, + {"type":"Punctuation","value":"();"}, + {"type":"Text","value":"\n"}, + {"type":"Operator","value":"#"}, + {"type":"NameBuiltin","value":"cube"}, + {"type":"Text","value":" "}, + {"type":"Punctuation","value":"(["}, + {"type":"LiteralNumber","value":"5"}, + {"type":"Punctuation","value":","}, + {"type":"LiteralNumber","value":"5"}, + {"type":"Punctuation","value":","}, + {"type":"LiteralNumber","value":"5"}, + {"type":"Punctuation","value":"]);"}, + {"type":"Text","value":"\n"}, + {"type":"NameBuiltin","value":"echo"}, + {"type":"Punctuation","value":"("}, + {"type":"LiteralStringDouble","value":"\"done\""}, + {"type":"Punctuation","value":");"}, + {"type":"Text","value":"\n \n"}, + {"type":"KeywordDeclaration","value":"function"}, + {"type":"Text","value":" "}, + {"type":"NameFunction","value":"func0"}, + {"type":"Punctuation","value":"()"}, + {"type":"Text","value":" "}, + {"type":"Operator","value":"="}, + {"type":"Text","value":" "}, + {"type":"LiteralNumber","value":"5"}, + {"type":"Punctuation","value":";"}, + {"type":"Text","value":"\n"}, + {"type":"KeywordDeclaration","value":"function"}, + {"type":"Text","value":" "}, + {"type":"NameFunction","value":"func1"}, + {"type":"Punctuation","value":"("}, + {"type":"Name","value":"x"}, + {"type":"Operator","value":"="}, + {"type":"LiteralNumber","value":"3"}, + {"type":"Punctuation","value":")"}, + {"type":"Text","value":" "}, + {"type":"Operator","value":"="}, + {"type":"Text","value":" "}, + {"type":"LiteralNumber","value":"2"}, + {"type":"Operator","value":"*"}, + {"type":"Name","value":"x"}, + {"type":"Operator","value":"+"}, + {"type":"LiteralNumber","value":"1"}, + {"type":"Punctuation","value":";"}, + {"type":"Text","value":"\n"}, + {"type":"KeywordDeclaration","value":"function"}, + {"type":"Text","value":" "}, + {"type":"NameFunction","value":"func2"}, + {"type":"Punctuation","value":"()"}, + {"type":"Text","value":" "}, + {"type":"Operator","value":"="}, + {"type":"Text","value":" "}, + {"type":"Punctuation","value":"["}, + {"type":"LiteralNumber","value":"1"}, + {"type":"Punctuation","value":","}, + {"type":"LiteralNumber","value":"2"}, + {"type":"Punctuation","value":","}, + {"type":"LiteralNumber","value":"3"}, + {"type":"Punctuation","value":","}, + {"type":"LiteralNumber","value":"4"}, + {"type":"Punctuation","value":"];"}, + {"type":"Text","value":"\n"}, + {"type":"KeywordDeclaration","value":"function"}, + {"type":"Text","value":" "}, + {"type":"NameFunction","value":"func3"}, + {"type":"Punctuation","value":"("}, + {"type":"Name","value":"y"}, + {"type":"Operator","value":"="}, + {"type":"LiteralNumber","value":"7"}, + {"type":"Punctuation","value":")"}, + {"type":"Text","value":" "}, + {"type":"Operator","value":"="}, + {"type":"Text","value":" "}, + {"type":"Punctuation","value":"("}, + {"type":"Name","value":"y"}, + {"type":"Operator","value":"=="}, + {"type":"LiteralNumber","value":"7"}, + {"type":"Punctuation","value":")"}, + {"type":"Text","value":" "}, + {"type":"Operator","value":"?"}, + {"type":"Text","value":" "}, + {"type":"LiteralNumber","value":"5"}, + {"type":"Text","value":" "}, + {"type":"Punctuation","value":":"}, + {"type":"Text","value":" "}, + {"type":"LiteralNumber","value":"2"}, + {"type":"Text","value":" "}, + {"type":"Punctuation","value":";"}, + {"type":"Text","value":"\n"}, + {"type":"KeywordDeclaration","value":"function"}, + {"type":"Text","value":" "}, + {"type":"NameFunction","value":"func4"}, + {"type":"Punctuation","value":"("}, + {"type":"Name","value":"p0"}, + {"type":"Punctuation","value":","}, + {"type":"Name","value":"p1"}, + {"type":"Punctuation","value":","}, + {"type":"Name","value":"p2"}, + {"type":"Punctuation","value":","}, + {"type":"Name","value":"p3"}, + {"type":"Punctuation","value":")"}, + {"type":"Text","value":" "}, + {"type":"Operator","value":"="}, + {"type":"Text","value":" "}, + {"type":"Punctuation","value":"["}, + {"type":"Name","value":"p0"}, + {"type":"Punctuation","value":","}, + {"type":"Name","value":"p1"}, + {"type":"Punctuation","value":","}, + {"type":"Name","value":"p2"}, + {"type":"Punctuation","value":","}, + {"type":"Name","value":"p3"}, + {"type":"Punctuation","value":"];"}, + {"type":"Text","value":"\n \n"}, + {"type":"NameBuiltin","value":"echo"}, + {"type":"Text","value":" "}, + {"type":"Punctuation","value":"("}, + {"type":"Name","value":"func0"}, + {"type":"Punctuation","value":"());"}, + {"type":"Text","value":" "}, + {"type":"CommentSingle","value":"// 5\n"}, + {"type":"Name","value":"a"}, + {"type":"Text","value":" "}, + {"type":"Operator","value":"="}, + {"type":"Text","value":" "}, + {"type":"Name","value":"func1"}, + {"type":"Punctuation","value":"();"}, + {"type":"Text","value":" "}, + {"type":"CommentSingle","value":"// 7\n"}, + {"type":"Name","value":"b"}, + {"type":"Operator","value":"="}, + {"type":"Text","value":" "}, + {"type":"Name","value":"func1"}, + {"type":"Punctuation","value":"("}, + {"type":"LiteralNumber","value":"5"}, + {"type":"Punctuation","value":");"}, + {"type":"Text","value":" "}, + {"type":"CommentSingle","value":"// 11\n"}, + {"type":"NameBuiltin","value":"echo"}, + {"type":"Text","value":" "}, + {"type":"Punctuation","value":"("}, + {"type":"Name","value":"func2"}, + {"type":"Punctuation","value":"());"}, + {"type":"Text","value":" "}, + {"type":"CommentSingle","value":"// [1, 2, 3, 4]\n"}, + {"type":"NameBuiltin","value":"echo"}, + {"type":"Punctuation","value":"("}, + {"type":"Text","value":" "}, + {"type":"Name","value":"func3"}, + {"type":"Punctuation","value":"("}, + {"type":"LiteralNumber","value":"2"}, + {"type":"Punctuation","value":"),"}, + {"type":"Name","value":"func3"}, + {"type":"Punctuation","value":"());"}, + {"type":"Text","value":" "}, + {"type":"CommentSingle","value":"// 2, 5\n"}, + {"type":"Text","value":" \n"}, + {"type":"Name","value":"z"}, + {"type":"Operator","value":"="}, + {"type":"Text","value":" "}, + {"type":"Name","value":"func4"}, + {"type":"Punctuation","value":"("}, + {"type":"Name","value":"func0"}, + {"type":"Punctuation","value":"(),"}, + {"type":"Name","value":"func1"}, + {"type":"Punctuation","value":"(),"}, + {"type":"Name","value":"func2"}, + {"type":"Punctuation","value":"(),"}, + {"type":"Name","value":"func3"}, + {"type":"Punctuation","value":"());"}, + {"type":"Text","value":" "}, + {"type":"CommentSingle","value":"// [5, 7, [1, 2, 3, 4], 5]\n"}, + {"type":"Text","value":" \n"}, + {"type":"NameBuiltin","value":"translate"}, + {"type":"Punctuation","value":"(["}, + {"type":"LiteralNumber","value":"0"}, + {"type":"Punctuation","value":","}, + {"type":"Operator","value":"-"}, + {"type":"LiteralNumber","value":"4"}, + {"type":"Operator","value":"*"}, + {"type":"Name","value":"func0"}, + {"type":"Punctuation","value":"(),"}, + {"type":"LiteralNumber","value":"0"}, + {"type":"Punctuation","value":"])"}, + {"type":"NameBuiltin","value":"cube"}, + {"type":"Punctuation","value":"(["}, + {"type":"Name","value":"func0"}, + {"type":"Punctuation","value":"(),"}, + {"type":"LiteralNumber","value":"2"}, + {"type":"Operator","value":"*"}, + {"type":"Name","value":"func0"}, + {"type":"Punctuation","value":"(),"}, + {"type":"Name","value":"func0"}, + {"type":"Punctuation","value":"()]);"}, + {"type":"Text","value":"\n\n"}, + {"type":"KeywordNamespace","value":"module"}, + {"type":"Text","value":" "}, + {"type":"NameNamespace","value":"parallelogram"}, + {"type":"Punctuation","value":"("}, + {"type":"Name","value":"x"}, + {"type":"Operator","value":"="}, + {"type":"LiteralNumber","value":"1"}, + {"type":"Punctuation","value":","}, + {"type":"Name","value":"y"}, + {"type":"Operator","value":"="}, + {"type":"LiteralNumber","value":"1"}, + {"type":"Punctuation","value":","}, + {"type":"Name","value":"angle"}, + {"type":"Operator","value":"="}, + {"type":"LiteralNumber","value":"90"}, + {"type":"Punctuation","value":")"}, + {"type":"Text","value":"\n "}, + {"type":"Punctuation","value":"{"}, + {"type":"NameBuiltin","value":"polygon"}, + {"type":"Punctuation","value":"([["}, + {"type":"LiteralNumber","value":"0"}, + {"type":"Punctuation","value":","}, + {"type":"LiteralNumber","value":"0"}, + {"type":"Punctuation","value":"],["}, + {"type":"Name","value":"x"}, + {"type":"Punctuation","value":","}, + {"type":"LiteralNumber","value":"0"}, + {"type":"Punctuation","value":"],"}, + {"type":"Text","value":"\n "}, + {"type":"Punctuation","value":"["}, + {"type":"Name","value":"x"}, + {"type":"Operator","value":"+"}, + {"type":"Name","value":"x"}, + {"type":"Operator","value":"*"}, + {"type":"NameBuiltin","value":"cos"}, + {"type":"Punctuation","value":"("}, + {"type":"Name","value":"angle"}, + {"type":"Punctuation","value":")"}, + {"type":"Operator","value":"/"}, + {"type":"NameBuiltin","value":"sin"}, + {"type":"Punctuation","value":"("}, + {"type":"Name","value":"angle"}, + {"type":"Punctuation","value":"),"}, + {"type":"Name","value":"y"}, + {"type":"Punctuation","value":"],"}, + {"type":"Text","value":"\n "}, + {"type":"Punctuation","value":"["}, + {"type":"Name","value":"x"}, + {"type":"Operator","value":"*"}, + {"type":"NameBuiltin","value":"cos"}, + {"type":"Punctuation","value":"("}, + {"type":"Name","value":"angle"}, + {"type":"Punctuation","value":")"}, + {"type":"Operator","value":"/"}, + {"type":"NameBuiltin","value":"sin"}, + {"type":"Punctuation","value":"("}, + {"type":"Name","value":"angle"}, + {"type":"Punctuation","value":"),"}, + {"type":"Name","value":"y"}, + {"type":"Punctuation","value":"]]);};"}, + {"type":"Text","value":"\n \n"}, + {"type":"Name","value":"parallelogram"}, + {"type":"Punctuation","value":"("}, + {"type":"LiteralNumber","value":"10"}, + {"type":"Punctuation","value":","}, + {"type":"LiteralNumber","value":"10"}, + {"type":"Punctuation","value":","}, + {"type":"LiteralNumber","value":"35"}, + {"type":"Punctuation","value":");"}, + {"type":"Text","value":"\n\n "}, + {"type":"KeywordDeclaration","value":"function"}, + {"type":"Text","value":" "}, + {"type":"NameFunction","value":"add_up_to"}, + {"type":"Punctuation","value":"("}, + {"type":"Name","value":"n"}, + {"type":"Punctuation","value":")"}, + {"type":"Text","value":" "}, + {"type":"Operator","value":"="}, + {"type":"Text","value":" "}, + {"type":"Punctuation","value":"("}, + {"type":"Text","value":" "}, + {"type":"Name","value":"n"}, + {"type":"Operator","value":"=="}, + {"type":"LiteralNumber","value":"0"}, + {"type":"Text","value":" "}, + {"type":"Operator","value":"?"}, + {"type":"Text","value":" "}, + {"type":"LiteralNumber","value":"0"}, + {"type":"Text","value":" "}, + {"type":"Punctuation","value":":"}, + {"type":"Text","value":" "}, + {"type":"Name","value":"n"}, + {"type":"Text","value":" "}, + {"type":"Operator","value":"+"}, + {"type":"Text","value":" "}, + {"type":"Name","value":"add_up_to"}, + {"type":"Punctuation","value":"("}, + {"type":"Name","value":"n"}, + {"type":"Operator","value":"-"}, + {"type":"LiteralNumber","value":"1"}, + {"type":"Punctuation","value":")"}, + {"type":"Text","value":" "}, + {"type":"Punctuation","value":");"}, + {"type":"Text","value":"\n"} +]