mirror of
https://github.com/Reuh/anselme.git
synced 2025-10-28 00:59:31 +00:00
Changed a few things
- Bumped to 0.15.0 - Add boot script - Change variable definition syntax, using a = to distinguish more cleary between identifier and value - Variables initial values are evaluated on first use instead of at parsing time - Error on variable redefinition. Means you should make sure to load saves after your scripts. - Improve string parsing, support for escape codes - Remove support for number literals with empty decimal part (42. for 42.0) as there's no distinction in Anselme and it conflicts with .function call suffix - Changed priority of : pair operator - Add type type, and type annotations to variables and function parameters - Change Lua function system to use regular Anselme functions - Defining a function from Lua is now way simpler and require providing a full Anselme function signature - Change Anselme function system - Dynamic dispatch, based on arity, type annotation and parameter names. Will select the most specific function at runtime. - Define way to overload most operators - Allow custom type to text formatters - Allow assignment to custom functions - Index operator ( renamed to () - Functions with parameters each have their own private namespace (scoping ersatz) - Internal: "custom"-mode operators now have their own expression AST type instead of cluttering the function system - Remove static type checker as it is barely useful with new function system. May or may not rewrite one in the future. - Improve error messages here and there - Internal: cleaning
This commit is contained in:
parent
4b139019c9
commit
64bc85741a
86 changed files with 2096 additions and 1012 deletions
|
|
@ -4,22 +4,44 @@ local parse_text
|
|||
-- * true: if success
|
||||
-- * nil, error: in case of error
|
||||
local function parse(state)
|
||||
-- expression parsing
|
||||
for _, l in ipairs(state.queued_lines) do
|
||||
local line, namespace = l.line, l.namespace
|
||||
-- default arguments
|
||||
-- default arguments and type annotation
|
||||
if line.type == "function" then
|
||||
for i, param in ipairs(line.params) do
|
||||
for _, param in ipairs(line.params) do
|
||||
-- get type annotation
|
||||
if param.type_annotation then
|
||||
local type_exp, rem = expression(param.type_annotation, state, namespace)
|
||||
if not type_exp then return nil, ("in type annotation, %s; at %s"):format(rem, line.source) end
|
||||
if rem:match("[^%s]") then
|
||||
return nil, ("unexpected characters after parameter %q: %q; at %s"):format(param.full_name, rem, line.source)
|
||||
end
|
||||
param.type_annotation = type_exp
|
||||
end
|
||||
-- get default value
|
||||
if param.default then
|
||||
local exp, rem = expression(param.default, state, namespace)
|
||||
if not exp then return nil, ("%s; at %s"):format(rem, line.source) end
|
||||
if rem:match("[^%s]") then return nil, ("expected end of expression before %q; at %s"):format(rem, line.source) end
|
||||
param.default = exp
|
||||
-- complete type information
|
||||
if exp.return_type then
|
||||
line.variant.types[i] = exp.return_type
|
||||
local default_exp, rem = expression(param.default, state, namespace)
|
||||
if not default_exp then return nil, ("in default value, %s; at %s"):format(rem, line.source) end
|
||||
if rem:match("[^%s]") then
|
||||
return nil, ("unexpected characters after parameter %q: %q; at %s"):format(param.full_name, rem, line.source)
|
||||
end
|
||||
param.default = default_exp
|
||||
-- extract type annotation from default value
|
||||
if default_exp.type == "function" and default_exp.called_name == "::" then
|
||||
param.type_annotation = default_exp.argument.expression.right
|
||||
end
|
||||
end
|
||||
end
|
||||
-- assignment argument
|
||||
if line.assignment and line.assignment.type_annotation then
|
||||
local type_exp, rem = expression(line.assignment.type_annotation, state, namespace)
|
||||
if not type_exp then return nil, ("in type annotation, %s; at %s"):format(rem, line.source) end
|
||||
if rem:match("[^%s]") then
|
||||
return nil, ("unexpected characters after parameter %q: %q; at %s"):format(line.assignment.full_name, rem, line.source)
|
||||
end
|
||||
line.assignment.type_annotation = type_exp
|
||||
end
|
||||
end
|
||||
-- expressions
|
||||
if line.expression then
|
||||
|
|
@ -27,17 +49,9 @@ local function parse(state)
|
|||
if not exp then return nil, ("%s; at %s"):format(rem, line.source) end
|
||||
if rem:match("[^%s]") then return nil, ("expected end of expression before %q; at %s"):format(rem, line.source) end
|
||||
line.expression = exp
|
||||
-- function return type information
|
||||
if line.type == "return" then
|
||||
local variant = line.parent_function.variant
|
||||
local return_type = line.expression.return_type
|
||||
if return_type then
|
||||
if not variant.return_type then
|
||||
variant.return_type = return_type
|
||||
elseif variant.return_type ~= return_type then
|
||||
return nil, ("trying to return a %s in a function that returns a %s; at %s"):format(return_type, variant.return_type, line.source)
|
||||
end
|
||||
end
|
||||
-- variable pending definition: expression will be evaluated when variable is needed
|
||||
if line.type == "definition" then
|
||||
state.variables[line.fqm].value.expression = line.expression
|
||||
end
|
||||
end
|
||||
-- text
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue