1
1
mirror of https://github.com/kanaka/mal.git synced 2024-08-17 17:50:24 +03:00
mal/impls/tcl/printer.tcl
Joel Martin 8a19f60386 Move implementations into impls/ dir
- Reorder README to have implementation list after "learning tool"
  bullet.

- This also moves tests/ and libs/ into impls. It would be preferrable
  to have these directories at the top level.  However, this causes
  difficulties with the wasm implementations which need pre-open
  directories and have trouble with paths starting with "../../". So
  in lieu of that, symlink those directories to the top-level.

- Move the run_argv_test.sh script into the tests directory for
  general hygiene.
2020-02-10 23:50:16 -06:00

57 lines
1.8 KiB
Tcl

proc format_list {elements start_char end_char readable} {
set res {}
foreach element $elements {
lappend res [pr_str $element $readable]
}
set joined [join $res " "]
return "${start_char}${joined}${end_char}"
}
proc format_hashmap {dictionary readable} {
set lst {}
dict for {keystr valobj} $dictionary {
lappend lst [string_new $keystr]
lappend lst $valobj
}
format_list $lst "\{" "\}" $readable
}
proc format_string {str readable} {
if {[string index $str 0] == "\u029E"} {
return ":[string range $str 1 end]"
} elseif {$readable} {
set escaped [string map {"\n" "\\n" "\"" "\\\"" "\\" "\\\\"} $str]
return "\"$escaped\""
} else {
return $str
}
}
proc format_function {funcdict} {
set type "function"
if {[dict get $funcdict is_macro]} {
set type "macro"
}
return "<$type:args=[join [dict get $funcdict binds] ","]>"
}
proc pr_str {ast readable} {
set nodetype [obj_type $ast]
set nodevalue [obj_val $ast]
switch $nodetype {
nil { return "nil" }
true { return "true" }
false { return "false" }
integer { return $nodevalue }
symbol { return $nodevalue }
string { return [format_string $nodevalue $readable] }
list { return [format_list $nodevalue "(" ")" $readable] }
vector { return [format_list $nodevalue "\[" "\]" $readable] }
hashmap { return [format_hashmap [dict get $nodevalue] $readable] }
atom { return "(atom [pr_str $nodevalue $readable])" }
function { return [format_function $nodevalue] }
nativefunction { return "<nativefunction:$nodevalue>" }
default { error "cannot print type $nodetype" }
}
}