You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
96 lines
2.9 KiB
96 lines
2.9 KiB
import { DataTypes } from './datatypes.js'; |
|
import { Env } from './env.js'; |
|
|
|
export class Printer { |
|
static princToString(sexp) { |
|
if (sexp.type === DataTypes.Cons) { |
|
if (sexp.car.type === DataTypes.Symbol && |
|
['QUOTE', 'QUASIQUOTE', 'UNQUOTE', 'UNQUOTE-SPLICING'].includes(sexp.car.value)) { |
|
let prefix = ''; |
|
switch (sexp.car.value) { |
|
case 'QUOTE': prefix = '\''; break; |
|
case 'QUASIQUOTE': prefix = '`'; break; |
|
case 'UNQUOTE': prefix = ','; break; |
|
case 'UNQUOTE-SPLICING': prefix = ',@'; break; |
|
} |
|
return prefix + Printer.princToString(sexp.cdr.car); |
|
} else { |
|
let result = Printer.princToString(sexp.car); |
|
if (sexp.cdr.type !== DataTypes.Nil && sexp.cdr.type === DataTypes.Cons) { |
|
let s = Printer.princToString(sexp.cdr); |
|
result += ' ' + s.substr(1, s.length - 2); |
|
} else if (sexp.cdr.type !== DataTypes.Nil) { |
|
result += ' . ' + Printer.princToString(sexp.cdr); |
|
} |
|
return '(' + result.trim() + ')'; |
|
} |
|
} |
|
switch(sexp.type) { |
|
case DataTypes.String: |
|
// return `"${sexp.value}"`; |
|
return `${sexp.value}`; |
|
case DataTypes.Symbol: |
|
return sexp.value.toUpperCase(); |
|
case DataTypes.Number: |
|
return `${sexp.value}`; |
|
case DataTypes.Function: |
|
return `<FUNCTION ${sexp.value}>`; |
|
case DataTypes.True: |
|
return 'T'; |
|
case DataTypes.Nil: |
|
return 'NIL'; |
|
} |
|
} |
|
|
|
static prin1ToString(sexp) { |
|
if (sexp.type === DataTypes.Cons) { |
|
if (sexp.car.type === DataTypes.Symbol && |
|
['QUOTE', 'QUASIQUOTE', 'UNQUOTE', 'UNQUOTE-SPLICING'].includes(sexp.car.value)) { |
|
let prefix = ''; |
|
switch (sexp.car.value) { |
|
case 'QUOTE': prefix = '\''; break; |
|
case 'QUASIQUOTE': prefix = '`'; break; |
|
case 'UNQUOTE': prefix = ','; break; |
|
case 'UNQUOTE-SPLICING': prefix = ',@'; break; |
|
} |
|
return prefix + Printer.princToString(sexp.cdr.car); |
|
} else { |
|
let result = Printer.princToString(sexp.car); |
|
if (sexp.cdr.type !== DataTypes.Nil && sexp.cdr.type === DataTypes.Cons) { |
|
let s = Printer.princToString(sexp.cdr); |
|
result += ' ' + s.substr(1, s.length - 2); |
|
} else if (sexp.cdr.type !== DataTypes.Nil) { |
|
result += ' . ' + Printer.princToString(sexp.cdr); |
|
} |
|
return '(' + result.trim() + ')'; |
|
} |
|
} |
|
switch(sexp.type) { |
|
case DataTypes.String: |
|
return `"${sexp.value}"`; |
|
case DataTypes.Symbol: |
|
return sexp.value.toUpperCase(); |
|
case DataTypes.Number: |
|
return `${sexp.value}`; |
|
case DataTypes.Function: |
|
return `<FUNCTION ${sexp.value}>`; |
|
case DataTypes.True: |
|
return 'T'; |
|
case DataTypes.Nil: |
|
return 'NIL'; |
|
} |
|
} |
|
|
|
static princ(sexp, env) { |
|
Env.get(env, 'STANDARD-OUTPUT-STREAM').pushData(Printer.princToString(sexp)/*.trim()*/); |
|
} |
|
|
|
static print(sexp, env) { |
|
Env.get(env, 'STANDARD-OUTPUT-STREAM').pushData('\n'); |
|
Printer.princ(sexp, env); |
|
} |
|
|
|
static prin1(sexp, env) { |
|
Env.get(env, 'STANDARD-OUTPUT-STREAM').pushData(Printer.prin1ToString(sexp)/*.trim()*/); |
|
} |
|
}
|
|
|