--- /dev/null
+-- static partial checkings for Lua.
+--
+-- This program checks some metalua or plain lua source code for most common
+-- mistakes. Its design focuses on the ability to check plain lua code: there is
+-- no need to load any extension in the module.
+--
+-- The current checkings include:
+--
+-- * Listing all free variables, and make sure they are declared.
+-- * For free vars known as modules, check that indexings in them are also
+-- declared.
+-- * When the type of something is known, do some basic type checkings. These
+-- checkings are by no means exhaustive; however, when a parameter function
+-- is constant or statically declared, it's checked.
+
+
+
+--[[
+Type grammar:
+
+t ::=
+| t and t
+| t or t
+| function (t, ...) return t, ... end
+| { (k=t)... }
+| table(t, t)
+| string
+| number
+| integer
+| boolean
+| userdata
+| nil
+| multi(t, ...)
+| _
+
+--]]
+
+
+match function get_type
+| `Number{...} -> return +{number}
+| `String{...} -> return +{string}
+| `True|`False -> return +{boolean}
+| `Nil -> return +{nil}
+| `Dots -> return +{_}
+| `Stat{_,v} -> return get_type(v)
+| `Paren{t} -> return get_one_type(t)
+| `Call{f, ...} ->
+ local ftype = get_type(f)
+ match ftype with
+ | `Function{ _, {`Return{result}} } -> return get_type(result)
+ | `Function{ _, {`Return{...} == results} } ->
+ local r2 = +{ multi() }
+ for r in ivalues(results) table.insert(r2, get_type(r)) end
+ return r2
+ | `And{...} -> return +{_} -- not implemented
+ | `Or{ a, b } -> match get_one_type(a), get_one_type(b) with
+ | `Function{...}==f1, `Function{...}==f2 ->
+ return `Op{ 'or', get_type(`Call{f1}), get_type(`Call{f2})}
+ | `Function{...}==f, _ | _, `Function{...}==f ->
+ return get_type(`Call{f})
+ | _ -> return +{_}
+ end
+| `Invoke{o, m, ... } == x -> return get_type(`Call{`Index{o, m}})
+| `Op{...}==o -> return get_op_type(o)
+| `Table{...}==t ->
+ local r = `Table{ }
+ for x in ivalues(t) do
+ match x with
+ | `Pair{ `String{...}==k, v } -> table.insert(r, `Pair{k, get_one_type(v)})
+ | t -> table.insert(r, get_one_type(t))
+ end
+ end
+ return r
+| `Function{...}==f ->
+| `Id{v} ->
+| `Index{t, k} -> match get_one_type(t), get_one_type(k) with
+ | `Call{`Id 'table', tk, tv }, _ -> return tv
+ | `Table{...}==tt, `Id 'string' ->
+
+local types_rt = require 'extension.types'
+
+function check_function(f, term)
+ match get_type(term) with
+ | `Function{ params, {`Return{...} == results}}, args ->
+ | `And{ a, b }, args ->
+ check_function(a, args)
+ check_function(b, args)
+ | `Or{ a, b }, args ->
+ if not pcall(check_function, a, args) then check_function(b, args) end
+ | `Id '_' -> -- pass
+ | _ -> error ("Call to a non-function")
+ end
+end
+
+function check_index(a, b, term)
+ match get_type(term) with
+ | `Table{}
+
+match function cfg.id.up
+| `Call{ f, ... } == x -> check_function (f, x)
+| `Index{ a, b } == x -> check_index (a, b, x)
+end
+
+
+-- List free vars
+cfg.id.
\ No newline at end of file
+++ /dev/null
--- static partial checkings for Lua.
---
--- This program checks some metalua or plain lua source code for most common
--- mistakes. Its design focuses on the ability to check plain lua code: there is
--- no need to load any extension in the module.
---
--- The current checkings include:
---
--- * Listing all free variables, and make sure they are declared.
--- * For free vars known as modules, check that indexings in them are also
--- declared.
--- * When the type of something is known, do some basic type checkings. These
--- checkings are by no means exhaustive; however, when a parameter function
--- is constant or statically declared, it's checked.
-
-
-
---[[
-Type grammar:
-
-t ::=
-| t and t
-| t or t
-| function (t, ...) return t, ... end
-| { (k=t)... }
-| table(t, t)
-| string
-| number
-| integer
-| boolean
-| userdata
-| nil
-| multi(t, ...)
-| _
-
---]]
-
-
-match function get_type
-| `Number{...} -> return +{number}
-| `String{...} -> return +{string}
-| `True|`False -> return +{boolean}
-| `Nil -> return +{nil}
-| `Dots -> return +{_}
-| `Stat{_,v} -> return get_type(v)
-| `Paren{t} -> return get_one_type(t)
-| `Call{f, ...} ->
- local ftype = get_type(f)
- match ftype with
- | `Function{ _, {`Return{result}} } -> return get_type(result)
- | `Function{ _, {`Return{...} == results} } ->
- local r2 = +{ multi() }
- for r in ivalues(results) table.insert(r2, get_type(r)) end
- return r2
- | `And{...} -> return +{_} -- not implemented
- | `Or{ a, b } -> match get_one_type(a), get_one_type(b) with
- | `Function{...}==f1, `Function{...}==f2 ->
- return `Op{ 'or', get_type(`Call{f1}), get_type(`Call{f2})}
- | `Function{...}==f, _ | _, `Function{...}==f ->
- return get_type(`Call{f})
- | _ -> return +{_}
- end
-| `Invoke{o, m, ... } == x -> return get_type(`Call{`Index{o, m}})
-| `Op{...}==o -> return get_op_type(o)
-| `Table{...}==t ->
- local r = `Table{ }
- for x in ivalues(t) do
- match x with
- | `Pair{ `String{...}==k, v } -> table.insert(r, `Pair{k, get_one_type(v)})
- | t -> table.insert(r, get_one_type(t))
- end
- end
- return r
-| `Function{...}==f ->
-| `Id{v} ->
-| `Index{t, k} -> match get_one_type(t), get_one_type(k) with
- | `Call{`Id 'table', tk, tv }, _ -> return tv
- | `Table{...}==tt, `Id 'string' ->
-
-
-
-local types_rt = require 'extension.types'
-
-
-
-
-function check_function(f, term)
- match get_type(term) with
- | `Function{ params, {`Return{...} == results}}, args ->
- | `And{ a, b }, args ->
- check_function(a, args)
- check_function(b, args)
- | `Or{ a, b }, args ->
- if not pcall(check_function, a, args) then check_function(b, args) end
- | `Id '_' -> -- pass
- | _ -> error ("Call to a non-function")
- end
-end
-
-function check_index(a, b, term)
- match get_type(term) with
- | `Table{}
-
-match function cfg.id.up
-| `Call{ f, ... } == x -> check_function (f, x)
-| `Index{ a, b } == x -> check_index (a, b, x)
-end
-
-
--- List free vars
-cfg.id.
\ No newline at end of file