;; -*- Mode: Irken -*-
(include "lib/core.scm")
(include "lib/pair.scm")
(include "lib/string.scm")
(defmacro format
(format) -> (list:nil)
(format (<int> n) item ...) -> (list:cons (int->string n) (format item ...))
(format (<char> ch) item ...) -> (list:cons (char->string ch) (format item ...))
(format (<bool> b) item ...) -> (list:cons (bool->string b) (format item ...))
(format (<string> s) item ...) -> (list:cons s (format item ...))
(format x item ...) -> (list:cons x (format item ...))
)
(print-string (string-join (format "testing" (int 1) (bool #t) (char #\A) "\n") " "))
beast:irken rushing$ tests/t_format testing 1 #t A #u {total ticks: 154666 gc ticks: 0}
Let me explain what's going on here. First, this is a macro definition. Macros are specified using a pattern language. To the left of each arrow is an input pattern - on the right is how that input will be transformed; before the code gets to the compiler (in other words, textual substitution).
Symbols surrounded by angle brackets are keywords - i.e., constant symbols. This is to distinguish them from variables. Every other name in the input pattern is bound to a variable, which can be used in the output form.
So the final line is transformed into this expression:
(print-string
(string-join
(list:cons "testing"
(list:cons (int->string 1)
(list:cons (bool->string #t)
(list:cons (char->string #\A)
(list:cons "\n" (list:nil))))))
" "))
This is actually a very simple macro, the patterns could be much more sophisticated, with embedded list structures and other keywords. But it creates the illusion of a variable-arity, variably-typed format function in a language that is strictly, statically typed and does not support variable arity! And of course other macros may be invoked. I'm sure I'll be expanding it as I work more on Irken's self-hosted back end.
Usually string formatting is an ugly part of any language - one of the classic problems with C is that the format language is ill-specified and dangerous. Only recently have compilers become smart enough to even do rudimentary checking...
I'm only just beginning to see what's possible with this macro system. I think the pattern matching syntax combines very nicely with the general pattern matching in the language.
No comments:
Post a Comment