summaryrefslogtreecommitdiff
path: root/prettyprint.c
diff options
context:
space:
mode:
Diffstat (limited to 'prettyprint.c')
-rw-r--r--prettyprint.c112
1 files changed, 94 insertions, 18 deletions
diff --git a/prettyprint.c b/prettyprint.c
index ce75371..ec00583 100644
--- a/prettyprint.c
+++ b/prettyprint.c
@@ -5,31 +5,77 @@
#include "dat.h"
#include "fns.h"
-Rune *prettyprintlist(Term *, Rune *, int, int, int, int);
-Rune *printlist(Term *, int, int, int);
+Rune *prettyprintlist(Term *, Rune *, int, int, int, int, Module *);
+Rune *printlist(Term *, int, int, int, Module *);
int islist(Term *);
+int needsquotes(Rune *);
Rune *
-prettyprint(Term *t, int quoted, int ignoreops, int numbervars)
+prettyprint(Term *t, int quoted, int ignoreops, int numbervars, Module *mod)
{
Rune *result;
Rune *args;
+ if(mod == nil)
+ mod = usermodule;
switch(t->tag){
case CompoundTerm:
- args = printlist(t, quoted, ignoreops, numbervars);
- if(args == nil){
- args = prettyprintlist(t->children, L", ", 0, quoted, ignoreops, numbervars);
- result = runesmprint("%S(%S)", t->text, args);
- free(args);
- }else
+ if(numbervars && t->arity == 1
+ && t->children->tag == IntegerTerm
+ && t->children->ival >= 0
+ && runestrcmp(t->text, L"$VAR") == 0){
+ vlong n = t->children->ival;
+ Rune i = L'A' + (n % 26);
+ vlong j = n / 26;
+ if(j == 0)
+ result = runesmprint("%C", i);
+ else
+ result = runesmprint("%C%lld", i, j);
+ break;
+ }
+ args = printlist(t, quoted, ignoreops, numbervars, mod);
+ if(args && !ignoreops){
result = runesmprint("[%S]", args);
+ free(args);
+ break;
+ }
+ Operator *op = getoperator(t->text, mod);
+ if(op == nil || ignoreops || !(t->arity == 1 || t->arity == 2)){
+ Rune *functor = prettyprint(mkatom(t->text), quoted, ignoreops, numbervars, mod);
+ args = prettyprintlist(t->children, L", ", 0, quoted, ignoreops, numbervars, mod);
+ result = runesmprint("%S(%S)", functor, args);
+ free(functor);
+ free(args);
+ break;
+ }else{
+ /* TODO:
+ 1) Only print spacing between op and args when needed
+ 2) currectly add () around args in special cases (see 7.10.5.h.2 in spec)
+ */
+ Rune *functor = prettyprint(mkatom(t->text), quoted, ignoreops, numbervars, mod);
+ Rune *arg1 = prettyprint(t->children, quoted, ignoreops, numbervars, mod);
+ Rune *arg2 = t->arity == 2 ? prettyprint(t->children->next, quoted, ignoreops, numbervars, mod) : nil;
+ if(t->arity == 2)
+ result = runesmprint("%S %S %S", arg1, functor, arg2);
+ else{
+ if(op->type == Xf || op->type == Yf)
+ result = runesmprint("%S %S", arg1, functor);
+ else
+ result = runesmprint("%S %S", functor, arg1);
+ }
+ free(functor);
+ free(arg1);
+ free(arg2);
+ }
break;
case AtomTerm:
- result = runesmprint("%S", t->text);
+ if(quoted && needsquotes(t->text))
+ result = runesmprint("'%S'", t->text);
+ else
+ result = runesmprint("%S", t->text);
break;
case VariableTerm:
- result = runesmprint("%S(%ulld)", t->text, t->clausenr);
+ result = runesmprint("_%S", t->text);
break;
case FloatTerm:
result = runesmprint("%f", t->dval);
@@ -46,7 +92,7 @@ prettyprint(Term *t, int quoted, int ignoreops, int numbervars)
}
Rune *
-prettyprintlist(Term *t, Rune *sep, int end, int quoted, int ignoreops, int numbervars)
+prettyprintlist(Term *t, Rune *sep, int end, int quoted, int ignoreops, int numbervars, Module *mod)
{
if(t == nil){
if(end)
@@ -55,8 +101,8 @@ prettyprintlist(Term *t, Rune *sep, int end, int quoted, int ignoreops, int numb
return runesmprint("");
}
- Rune *str = prettyprint(t, quoted, ignoreops, numbervars);
- Rune *rest = prettyprintlist(t->next, sep, end, quoted, ignoreops, numbervars);
+ Rune *str = prettyprint(t, quoted, ignoreops, numbervars, mod);
+ Rune *rest = prettyprintlist(t->next, sep, end, quoted, ignoreops, numbervars, mod);
Rune *result;
if(t->next != nil)
@@ -71,7 +117,7 @@ prettyprintlist(Term *t, Rune *sep, int end, int quoted, int ignoreops, int numb
/* printlist prints a list's elements but not the surrounding [ and ] */
Rune *
-printlist(Term *list, int quoted, int ignoreops, int numbervars)
+printlist(Term *list, int quoted, int ignoreops, int numbervars, Module *mod)
{
if(list->tag != CompoundTerm || list->arity != 2 || runestrcmp(L".", list->text) != 0)
return nil;
@@ -79,20 +125,50 @@ printlist(Term *list, int quoted, int ignoreops, int numbervars)
Term *head = list->children;
Term *tail = head->next;
- Rune *headstr = prettyprint(head, quoted, ignoreops, numbervars);
+ Rune *headstr = prettyprint(head, quoted, ignoreops, numbervars, mod);
Rune *tailstr = nil;
Rune *result;
if(tail->tag == CompoundTerm && tail->arity == 2 && runestrcmp(L".", tail->text) == 0){
- tailstr = printlist(tail, quoted, ignoreops, numbervars);
+ tailstr = printlist(tail, quoted, ignoreops, numbervars, mod);
result = runesmprint("%S, %S", headstr, tailstr);
}else if(tail->tag == AtomTerm && runestrcmp(L"[]", tail->text) == 0){
result = runesmprint("%S", headstr);
}else{
- tailstr = prettyprint(tail, quoted, ignoreops, numbervars);
+ tailstr = prettyprint(tail, quoted, ignoreops, numbervars, mod);
result = runesmprint("%S | %S", headstr, tailstr);
}
free(headstr);
free(tailstr);
return result;
}
+
+int
+needsquotes(Rune *text)
+{
+ Rune *graphics = L"#$&*+-./:<=>?@^~\\"; /* keep in sync with lexer */
+ int len = runestrlen(text);
+ int i;
+
+ if(runestrcmp(text, L"") == 0)
+ return 1;
+
+ if(runestrchr(graphics, text[0])){
+ for(i = 0; i < len; i++){
+ if(!runestrchr(graphics, text[i]))
+ return 1;
+ }
+ return 0;
+ }
+
+ if(len == 1 && runestrchr(L";!,", text[0]))
+ return 0;
+
+ if(len > 0 && !islowerrune(text[0]))
+ return 1;
+
+ for(i = 0; i < len; i++)
+ if(!isalpharune(text[i]))
+ return 1;
+ return 0;
+} \ No newline at end of file