Score
0
Watch 4 Star 3 Fork 0

Li Jin / MoonPlusC++MIT

Join us
Explore and code with more than 2 million developers,Free private repositories !:)
Sign up
用C++重写的Moonscript编译器。 spread retract

  • C++ 82.2%
  • MoonScript 8.7%
  • C 6.4%
  • Makefile 2.3%
  • CMake 0.4%
Clone or download
Cancel
Notice: Creating folder will generate an empty file .keep, because not support in Git
Loading...
README.md

MoonPlus

CI
MoonPlus is a compiler with features from Moonscript language 0.5.0 and implementing new features to make Moonscript more up to date.

Since original Moonscript has been used to write web framework lapis and run a few business web sites like itch.io and streak.club with some large code bases. The original language is getting too hard to adopt new language features for those may break the stablility for existing applications.

So MoonPlus is a new code base for pushing the language to go forward and may be a playground to try introducing new language syntax or programing paradigms to make Moonscript language more expressive and productive.

Features

  • No other dependencies needed except modified parserlib library from Achilleas Margaritis with some performance enhancement. lpeg library is no longer needed.
  • Written in C++17.
  • Support full Moonscript language features, generate the same Lua codes with original compiler.
  • Reserve line numbers from Moonscript sources in compiled Lua codes to help with debugging.

Installation

Install luarocks, a package manager for Lua modules. Then install Lua module with

> luarocks install moonplus

Usage

require("moonp")("main") -- require `main.moon`

local moonp = require("moonp")
print(moonp.to_lua[[
f = ->
  print "hello world"
f!
]],{
  implicit_return_root = true,
  reserve_line_number = false,
  lint_global = false
})

Changes

The original Moonscript language 0.5.0 support can be found in the 0.5.0 branch. Moonscript with new features is in the master branch. Here are the new features introduced in MoonPlus.

  • Multi-line comment.
  • Usage for symbol \ to escape new line. Will compile codes:
str = --[[
   This is a multi line comment.
   It's OK.
]] strA \ -- comment 1
   .. strB \ -- comment 2
   .. strC

func --[[ip]] "192.168.126.110", --[[port]] 3000

  to:

local str = strA .. strB .. strC
func("192.168.126.110", 3000)
  • Back call features with new operator and syntax. For example:
{1,2,3} \
  |> map((x)-> x * 2) \
  |> filter((x)-> x > 4) \
  |> reduce(0, (a,b)-> a + b) \
  |> print

do
  (data) <- http.get "ajaxtest"
  body[".result"]\html data
  (processed) <- http.post "ajaxprocess", data
  body[".result"]\append processed
  print "done"

  will be compiled to:

print(reduce(filter(map({
  1,
  2,
  3
}, function(x)
  return x * 2
end), function(x)
  return x > 4
end), 0, function(a, b)
  return a + b
end))
do
  http.get("ajaxtest", function(data)
    body[".result"]:html(data)
    return http.post("ajaxprocess", data, function(processed)
      body[".result"]:append(processed)
      return print("done")
    end)
  end)
end
  • Existential operator support. Generate codes from:
func?!

x = tab?.value

print abc?["hello world"]?.xyz

if print and x?
  print x

  to:

if func ~= nil then
  func()
end
local x
if tab ~= nil then
  x = tab.value
end
print((function()
  if abc ~= nil then
    local _obj_0 = abc["hello world"]
    if _obj_0 ~= nil then
      return _obj_0.xyz
    end
    return nil
  end
  return nil
end)())
if print and (x ~= nil) then
  print(x)
end
  • More usages for import keyword. Will compile codes from:
import 'module'
import "module.part"
import "d-a-s-h-e-s"
import "player" as Player
import "lpeg" as {:C, :Ct, :Cmt}

  to:

local module = require('module')
local part = require("module.part")
local d_a_s_h_e_s = require("d-a-s-h-e-s")
local Player = require("player")
local C, Ct, Cmt
do
  local _obj_0 = require("lpeg")
  C, Ct, Cmt = _obj_0.C, _obj_0.Ct, _obj_0.Cmt
end
  • Can do slash call with Lua keywords. Generate codes from:
c.repeat.if\then("xyz")\else res

  to:

local _call_3 = c["repeat"]["if"]
local _call_4 = _call_3["then"](_call_3, "xyz")
_call_4["else"](_call_4, res)
  • Feature of Reusing variable which helps generate reduced Lua codes. For example, MoonPlus will generate codes from:
with leaf
  .world 1,2,3

with leaf
  g = .what.is.this
  print g

for x in *something
  print x

  to:

leaf.world(1, 2, 3)
do
  local g = leaf.what.is.this
  print(g)
end
for _index_0 = 1, #something do
  local x = something[_index_0]
  print(x)
end

  instead of:

do
  local _with_0 = leaf
  _with_0.world(1, 2, 3)
end
do
  local _with_0 = leaf
  local g = _with_0.what.is.this
end
local _list_0 = something
for _index_0 = 1, #_list_0 do
  local x = _list_0[_index_0]
  print(x)
end
  • Expression list appears at the middle of code block is not allowed. For codes like:
-- Moonscript 0.5.0
f = (x)->
  "abc",123 -- valid meaningless codes
  x + 1

in original Moonscript compiles to:

local f
f = function(x)
 local _ = "abc", 123 -- report error in MoonPlus
 return x + 1
end

This feature may lead to some silenced errors. For example:

-- expected codes
tree\addChild with Node!
  \addChild subNode
  
-- in original Moonscript, codes will still run after adding a break
tree\addChild
with Node!
   \addChild subNode

the original Moonscript will compile these codes to:

-- expected codes
tree:addChild((function()
  do
    local _with_0 = Node()
    _with_0:addChild(subNode)
    return _with_0
  end
end)())

-- codes added with a break will still run
local _ -- report error in MoonPlus instead of creating
do      -- an anonymous function to bind the object method
  local _base_0 = tree
  local _fn_0 = _base_0.addChild
  _ = function(...)
    return _fn_0(_base_0, ...)
  end
end
do
  local _with_0 = Node()
  _with_0:addChild(subNode)
end

Standalone Compiler Usage

Test compiler with make test. Run moonp complier in project folder with:

make
./moonp -h

License

MIT

Comments ( 0 )

Sign in for post a comment

C++
1
https://gitee.com/pig/MoonPlus.git
git@gitee.com:pig/MoonPlus.git
pig
MoonPlus
MoonPlus
master

Help Search