-
-
Notifications
You must be signed in to change notification settings - Fork 4
Closed
Labels
wontfixThis will not be worked onThis will not be worked on
Description
I know at this point it could be a heroic effort, but after looking at the parser for @aml
, I thought it would be appropriate to suggest usage of MacroTools.jl and their @capture
macro. It might be the biggest help around here:
AcuteML.jl/src/@aml/@aml_parse.jl
Lines 51 to 389 in 6b87580
######################## | |
# Single struct name - "aml name" | |
if isa(ei, String) | |
# struct_function[1]=missing # function | |
# Self-name checker | |
if ei == "~" | |
if T isa Symbol | |
struct_name = string(T) | |
elseif T isa Expr && T.head == :curly | |
struct_name = string(T.args[1]) # S | |
end | |
else | |
struct_name = ei # Type aml name | |
end | |
argsexpr.args[i] = nothing # removing "aml name" from expr args | |
struct_nodetype = AbsNormal | |
################################################################ | |
# Literal Struct name - empty"aml name" | |
elseif isa(ei, Tuple) | |
################################################################ | |
# Struct aml | |
######################## | |
# Literal only empty"aml name" | |
if isa(ei, Tuple{Type,String}) | |
# struct_function[1]=missing # function | |
# Self-name checker | |
if ei[2] == "~" | |
if T isa Symbol | |
struct_name = string(T) | |
elseif T isa Expr && T.head == :curly | |
struct_name = string(T.args[1]) # S | |
end | |
else | |
struct_name = ei[2] # Type aml name | |
end | |
struct_nodetype = ei[1] | |
struct_nodetype = aml_dispatch(struct_nodetype, struct_name) | |
argsexpr.args[i] = nothing # removing "aml name" from expr args | |
# Custom Code | |
elseif isa(ei, Tuple{Symbol, Expr}) | |
iMacro += 1 | |
# Row for code insertion (insert before iArg-th argument) | |
if ei[1] == :creator | |
args_custom_creator[iArg] = ei[2] | |
elseif ei[1] == :extractor | |
args_custom_extractor[iArg] = ei[2] | |
elseif ei[1] == :updater | |
args_custom_updater[iArg] = ei[2] | |
end | |
argsexpr.args[i] = nothing # removing custom code macro from expr args | |
end | |
elseif ei isa Expr && ei.head == :tuple | |
######################## | |
# Struct Function - "aml name", F | |
if isa(ei.args[1], String) && isa(ei.args[2], Union{Symbol,Function}) # "aml name", F | |
struct_function[1]=ei.args[2] # function | |
# Self-name checker | |
if ei.args[1] == "~" | |
if T isa Symbol | |
struct_name = string(T) | |
elseif T isa Expr && T.head == :curly | |
struct_name = string(T.args[1]) # S | |
end | |
else | |
struct_name = ei.args[1] # Type aml name | |
end | |
struct_nodetype = AbsNormal | |
argsexpr.args[i] = nothing # removing "aml name" from expr args | |
######################## | |
# Literal and Struct Function - empty"aml name", F | |
elseif isa(ei.args[1], Tuple) && isa(ei.args[2], Union{Symbol,Function}) | |
struct_function[1]=ei.args[2] # function | |
# Self-name checker | |
if ei.args[1][2] == "~" | |
if T isa Symbol | |
struct_name = string(T) | |
elseif T isa Expr && T.head == :curly | |
struct_name = string(T.args[1]) # S | |
end | |
else | |
struct_name = ei.args[1][2] # Type aml name | |
end | |
struct_nodetype = ei.args[1][1] | |
struct_nodetype = aml_dispatch(struct_nodetype, struct_name) | |
argsexpr.args[i] = nothing # removing "aml name" from expr args | |
################################################################ | |
# Arguments | |
######################## | |
# No Def Value | |
elseif ei.args[1] isa Union{Symbol,Expr} # var/var::T, "name" | |
# Def Value | |
# args_defaultvalue[iArg] = missing | |
# Type Checker | |
lhs = ei.args[1] | |
if lhs isa Symbol # var, "name" | |
var = ei.args[1] | |
args_type[iArg] = String # consider String as the type | |
args_param[iArg] = var | |
args_var[iArg] = var | |
argsexpr.args[i] = var # removing "name",... | |
elseif lhs isa Expr && lhs.head == :(::) && lhs.args[1] isa Symbol # var::T, "name" | |
var = lhs.args[1] | |
varType = lhs.args[2] # Type | |
args_type[iArg] = varType | |
args_param[iArg] = var | |
args_var[iArg] = var | |
argsexpr.args[i] = lhs # removing "name",... | |
end | |
# Literal Checker | |
if length(ei.args[2]) == 2 # literal | |
argAmlType = ei.args[2][1] | |
args_literaltype[iArg] = argAmlType # literal type | |
ni = ei.args[2][2] | |
# Self-name checker | |
if ni == "~" | |
args_name[iArg] = string(var) | |
else | |
args_name[iArg] = ni | |
end | |
else | |
args_literaltype[iArg] = AbsNormal # non-literal | |
ni = ei.args[2] | |
# Self-name checker | |
if ni == "~" | |
args_name[iArg] = string(var) | |
else | |
args_name[iArg] = ni | |
end | |
end | |
# Function Checker | |
if length(ei.args) == 3 && isa(ei.args[3], Union{Function, Symbol}) # var/var::T, "name", f | |
fun = ei.args[3] # function | |
args_function[iArg] = fun | |
# else # function name isn't given | |
# args_function[iArg] = missing | |
end | |
end # end Tuple sub possibilities | |
################################################################ | |
# Def Value | |
elseif ei isa Expr && ei.head == :(=) # def value provided | |
# aml name Checker | |
if ei.args[2] isa Expr && ei.args[2].head == :tuple # var/var::T = defVal, "name" | |
# Def Value | |
defVal = ei.args[2].args[1] | |
args_defaultvalue[iArg] = defVal | |
lhs = ei.args[1] | |
argsexpr.args[i] = lhs # remove =defVal for type definition | |
# Type Checker | |
if lhs isa Symbol # var = defVal, "name" | |
var = ei.args[1] | |
args_type[iArg] = String # consider String as the type | |
args_param[iArg] = Expr(:kw, var, defVal) | |
args_var[iArg] = var | |
argsexpr.args[i] = var # removing "name",... | |
elseif lhs isa Expr && lhs.head == :(::) && lhs.args[1] isa Symbol # var::T = defVal, "name" | |
var = lhs.args[1] | |
varType = lhs.args[2] # Type | |
args_type[iArg] = varType | |
args_param[iArg] = Expr(:kw, var, defVal) # TODO also put type expression | |
args_var[iArg] = var | |
argsexpr.args[i] = lhs # removing "name",... | |
end | |
# Literal Checker | |
if length(ei.args[2].args[2]) == 2 # literal | |
argAmlType = ei.args[2].args[2][1] | |
args_literaltype[iArg] = argAmlType # literal type | |
ni = ei.args[2].args[2][2] | |
# Self-name checker | |
if ni == "~" | |
args_name[iArg] = string(var) | |
else | |
args_name[iArg] = ni | |
end | |
else | |
args_literaltype[iArg] = AbsNormal # non-literal | |
ni = ei.args[2].args[2] | |
# Self-name checker | |
if ni == "~" | |
args_name[iArg] = string(var) | |
else | |
args_name[iArg] = ni | |
end | |
end | |
# Function Checker | |
if length(ei.args[2].args) == 3 && isa(ei.args[2].args[3], Union{Function, Symbol}) # var/var::T = defVal, "name", f | |
fun = ei.args[2].args[3] # function | |
args_function[iArg] = fun | |
# else # function name isn't given | |
# args_function[iArg] = missing | |
end | |
######################## | |
# No aml Name - But defVal | |
else # var/var::T = defVal # ignored for creating aml | |
# Type Checker | |
lhs = ei.args[1] | |
if lhs isa Symbol # var = defVal | |
defVal = ei.args[2] | |
args_defaultvalue[iArg] = defVal | |
# args_name[iArg] = missing # ignored for creating aml | |
# args_function[iArg] = missing # ignored for creating aml | |
var = ei.args[1] | |
args_type[iArg] = Any | |
args_param[iArg] = Expr(:kw, var, defVal) | |
args_var[iArg] = var | |
argsexpr.args[i] = var # remove =defVal for type definition | |
elseif lhs isa Expr && lhs.head == :(::) && lhs.args[1] isa Symbol # var::T = defVal | |
defVal = ei.args[2] | |
args_defaultvalue[iArg] = defVal | |
# args_name[iArg] = missing # ignored for creating aml | |
# args_function[iArg] = missing # ignored for creating aml | |
var = lhs.args[1] | |
varType = lhs.args[2] # Type | |
args_type[iArg] = varType | |
args_param[iArg] = Expr(:kw, var, defVal) # TODO also put type expression | |
args_var[iArg] = var | |
argsexpr.args[i] = lhs # remove =defVal for type definition | |
else | |
# something else, e.g. inline inner constructor | |
# F(...) = ... | |
continue | |
end | |
end | |
################################################################ | |
# No aml name - No defVal | |
else # var/var::T # ignored for creating aml | |
# Type Checker | |
if ei isa Symbol # var | |
# args_name[iArg] = missing # argument ignored for aml | |
# args_function[iArg] = missing # ignored for creating aml | |
args_type[iArg] = String | |
var = ei | |
args_param[iArg] = var | |
args_var[iArg] = var | |
elseif ei.head == :(::) && ei.args[1] isa Symbol # var::T | |
# args_name[iArg] = missing # argument ignored for aml | |
# args_function[iArg] = missing # ignored for creating aml | |
var = ei.args[1] | |
varType = ei.args[2] # Type | |
args_type[iArg] = varType | |
args_param[iArg] = var | |
args_var[iArg] = var | |
elseif ei.head == :block # anything else should be evaluated again | |
# can arise with use of @static inside type decl | |
argsexpr, args_param, args_defaultvalue, args_type, args_var, args_name, args_function, args_literaltype, struct_name, struct_nodetype, struct_function, is_struct_mutable, args_custom_creator, args_custom_extractor, args_custom_updater, T = aml_parse(expr) | |
else | |
continue | |
end |
Metadata
Metadata
Assignees
Labels
wontfixThis will not be worked onThis will not be worked on