1
1
mirror of https://github.com/kanaka/mal.git synced 2024-11-11 00:52:44 +03:00
mal/awk/types.awk
2015-08-26 10:13:25 +09:00

219 lines
4.5 KiB
Awk

# string"
# symbol '
# keyword :
# number +
# nil #
# true #
# false #
# list (
# vector [
# hash {
# atom ?
# builtin function &
# builtin function with meta %
# user defined function $
function types_allocate()
{
types_heap[types_heap_index]["ref"] = 1
return types_heap_index++
}
function types_addref(ast)
{
if (ast ~ /^[([{$%?]/) {
++types_heap[substr(ast, 2)]["ref"]
}
return ast
}
function types_release(ast, idx, ref, i, len)
{
switch (ast) {
case /^[([]/:
idx = substr(ast, 2)
ref = --types_heap[idx]["ref"]
if (ref <= 0) {
if (ref < 0) {
print "ref count error:" ast ", " ref
}
len = types_heap[idx]["len"]
for (i = 0; i < len; ++i) {
types_release(types_heap[idx][i])
}
types_release(types_heap[idx]["meta"])
delete types_heap[idx]
}
return
case /^\{/:
idx = substr(ast, 2)
ref = --types_heap[idx]["ref"]
if (ref <= 0) {
if (ref < 0) {
print "ref count error:" ast ", " ref
}
for (i in types_heap[idx]) {
if (i ~ /^[":]/) {
types_release(types_heap[idx][i])
}
}
types_release(types_heap[idx]["meta"])
delete types_heap[idx]
}
return
case /^\$/:
idx = substr(ast, 2)
ref = --types_heap[idx]["ref"]
if (ref <= 0) {
if (ref < 0) {
print "ref count error:" ast ", " ref
}
types_release(types_heap[idx]["params"])
types_release(types_heap[idx]["body"])
types_release(types_heap[idx]["meta"])
env_release(types_heap[idx]["env"])
delete types_heap[idx]
}
return
case /^%/:
idx = substr(ast, 2)
ref = --types_heap[idx]["ref"]
if (ref <= 0) {
if (ref < 0) {
print "ref count error:" ast ", " ref
}
types_release(types_heap[idx]["meta"])
delete types_heap[idx]
}
return
case /^\?/:
idx = substr(ast, 2)
ref = --types_heap[idx]["ref"]
if (ref <= 0) {
if (ref < 0) {
print "ref count error:" ast ", " ref
}
types_release(types_heap[idx]["obj"])
delete types_heap[idx]
}
}
}
function types_check(val, idx, len, i)
{
if (val !~ /^[([{?%$]/) {
return
}
idx = substr(val, 2)
if (!(idx in types_heap)) {
print "dangling reference " val
return
}
if (types_heap[idx]["checked"]++) {
return
}
#types_heap[idx]["checked"] = 1
switch (val) {
case /^[([]/:
if (!("len" in types_heap[idx])) {
print "length not found in " val
return
}
len = types_heap[idx]["len"]
for (i = 0; i < len; ++i) {
if (!(i in types_heap[idx])) {
print "sequence corrupted in " val " of " i
} else {
types_check(types_heap[idx][i])
}
}
types_check(types_heap[idx]["meta"])
return
case /^\{/:
for (i in types_heap[idx]) {
if (i != "ref") {
types_check(types_heap[idx][i])
}
}
return
case /^\?/:
if (!("obj" in types_heap[idx])) {
print "atom corrupted in " val
} else {
types_check(types_heap[idx]["obj"])
}
types_check(types_heap[idx]["meta"])
return
case /^%/:
if (!("func" in types_heap[idx])) {
print "function corrupted in " val
} else {
types_check(types_heap[idx]["func"])
}
types_check(types_heap[idx]["meta"])
return
case /^\$/:
if (!("body" in types_heap[idx])) {
print "function body corrupted in " val
} else {
types_check(types_heap[idx]["body"])
}
if (!("params" in types_heap[idx])) {
print "function params corrupted in " val
} else {
types_check(types_heap[idx]["params"])
}
if (!("env" in types_heap[idx])) {
print "function env corrupted in " val
} else {
env_check(types_heap[idx]["env"])
}
types_check(types_heap[idx]["meta"])
return
default:
print "unknown type " val
return
}
}
function types_dump(i, j)
{
for (i = 0; i < types_heap_index; i++) {
if (i in types_heap) {
if (isarray(types_heap[i])) {
if (!("checked" in types_heap[i]) || types_heap[i]["checked"] != types_heap[i]["ref"]) {
for (j in types_heap[i]) {
print " types_heap[" i "][" j "] = " types_heap[i][j]
}
}
} else {
print " types_heap[" i "] = " types_heap[i]
}
}
}
}
function types_typename(str)
{
switch (str) {
case /^"/: return "string"
case /^'/: return "symbol"
case /^:/: return "keyword"
case /^\+/: return "number"
case /^#nil$/: return "nil"
case /^#true$/: return "true"
case /^#false$/: return "false"
case /^\(/: return "list"
case /^\[/: return "vector"
case /^\{/: return "hash"
case /^\?/: return "atom"
case /^[&%]/: return "builtin function"
case /^\$/: return "user defined function"
}
}
BEGIN {
types_heap_index = 0
}