/**
* erlyberly, erlang trace debugger
* Copyright (C) 2016 Andy Till
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package erlyberly.format;
import java.util.ArrayList;
import com.ericsson.otp.erlang.OtpErlangAtom;
import com.ericsson.otp.erlang.OtpErlangBinary;
import com.ericsson.otp.erlang.OtpErlangList;
import com.ericsson.otp.erlang.OtpErlangObject;
import com.ericsson.otp.erlang.OtpErlangString;
import com.ericsson.otp.erlang.OtpErlangTuple;
import erlyberly.node.OtpUtil;
public class LFEFormatter implements TermFormatter {
/**
* Convert an MFA tuple to a string, where the MFA must have the type:
*
* {Module::atom(), Function::atom(), Args::[any()]}.
*/
@Override
public String modFuncArgsToString(OtpErlangTuple mfa) {
StringBuilder sb = new StringBuilder();
sb.append("(")
.append(mfa.elementAt(0))
.append(":")
.append(mfa.elementAt(1));
OtpErlangList args = (OtpErlangList) mfa.elementAt(2);
ArrayList<String> stringArgs = new ArrayList<>();
for (OtpErlangObject arg : args) {
stringArgs.add(toString(arg));
}
sb.append(String.join(", ", stringArgs))
.append(")");
return sb.toString();
}
@Override
public String modFuncArityToString(OtpErlangTuple mfa) {
StringBuilder sb = new StringBuilder();
OtpErlangList argsList = (OtpErlangList) mfa.elementAt(2);
sb.append("(")
.append(mfa.elementAt(0))
.append(":")
.append(mfa.elementAt(1))
.append("/").append(argsList.arity())
.append(")");
return sb.toString();
}
@Override
public String exceptionToString(OtpErlangAtom errorClass, OtpErlangObject errorReason) {
return toString(errorClass) + ": " + toString(errorReason);
}
@Override
public StringBuilder appendToString(OtpErlangObject obj, StringBuilder sb) {
if(obj instanceof OtpErlangAtom) {
sb.append("'").append(obj.toString());
}
else if(obj instanceof OtpErlangBinary) {
sb.append("#B(");
Formatting.binaryToString((OtpErlangBinary) obj, " ", sb);
sb.append(")");
}
else if(OtpUtil.isErlyberlyRecordField(obj)) {
OtpErlangObject fieldObj = ((OtpErlangTuple)obj).elementAt(2);
appendToString(fieldObj, sb);
}
else if(obj instanceof OtpErlangTuple) {
sb.append("#(");
elementsToString(sb, ((OtpErlangTuple) obj).elements());
sb.append(")");
}
else if(obj instanceof OtpErlangList) {
sb.append("(");
elementsToString(sb, ((OtpErlangList) obj).elements());
if(!((OtpErlangList) obj).isProper()) {
sb.append(cons());
appendToString(((OtpErlangList) obj).getLastTail(), sb);
}
sb.append(")");
}
else if(obj instanceof OtpErlangString) {
Formatting.appendString((OtpErlangString) obj, this, "\"", sb);
}
else {
sb.append(obj.toString());
}
return sb;
}
private void elementsToString(StringBuilder sb, OtpErlangObject[] elements) {
for(int i=0; i < elements.length; i++) {
if(i != 0) {
sb.append(", ");
}
appendToString(elements[i], sb);
}
}
@Override
public String emptyTupleString() {
return "#( )";
}
@Override
public String tupleLeftParen() {
return "#(";
}
@Override
public String tupleRightParen() {
return ")";
}
@Override
public String emptyListString() {
return "( )";
}
@Override
public String listLeftParen() {
return "(";
}
@Override
public String listRightParen() {
return ")";
}
@Override
public String mapLeft(OtpErlangObject obj) {
return "#M(";
}
@Override
public String mapRight() {
return ")";
}
@Override
public Boolean isHiddenField(OtpErlangObject key) {return false;}
@Override
public String cons() {
return ".";
}
}