summaryrefslogtreecommitdiff
path: root/clformat/src/main/java/bjc/utils/ioutils/format/directives/DecimalDirective.java
blob: 6447eefae4a04573a36765ff77d48c7a56abe6df (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
package bjc.utils.ioutils.format.directives;

import java.io.*;
import java.text.*;

import bjc.esodata.*;
import bjc.utils.ioutils.format.*;

/**
 * Implementation of the `D directive.
 *
 * This is the most general directive for printing out decimal-numbers (floating
 * point).
 *
 * @author Ben Culkin
 */
public class DecimalDirective implements Directive {
	@Override
	public Edict compile(CompileContext compCTX) {
		CLParameters params = compCTX.decr.parameters;
		@SuppressWarnings("unused")
		CLModifiers  mods   = compCTX.decr.modifiers;

		CLValue decForm = CLValue.nil();

		switch(params.length()) {
		case 0:
			// Use the default
			break;
		case 1:
			// Use the specified format
			params.mapIndices("format");

			decForm = params.resolveKey("format");
			break;
		default:
			// @TODO 16 Oct, 2020 - Ben Culkin - :Preformat
			// Add ability to specify a common/fixed set of formats
			//
			// @TODO 16 Oct, 2020 - Ben Culkin - :ErrorFix
			// Instead of using IllegalArgumentException here, use a custom
			// subtype of it with an appropriate name/auto-message forming
			throw new IllegalArgumentException("Must provide 0 or 1 arguments to `D directive");
		}

		return new DecimalEdict(decForm);
	}
}

class DecimalEdict implements Edict {
	private CLValue decFormat;

	public DecimalEdict(CLValue decForm) {
		this.decFormat = decForm;
	}

	@Override
	public void format(FormatContext formCTX) throws IOException {
		Tape<Object> itemTape = formCTX.items;

		CLFormatter.checkItem(itemTape.item(), "`D");

		NumberFormat numForm = NumberFormat.getInstance();

		String decFormString = decFormat.getValue(itemTape);

		if (decFormString == null || decFormString.equals("")) {
			// Use the default if not provided.
		} else {
			if (numForm instanceof DecimalFormat) {
				((DecimalFormat)numForm).applyPattern(decFormString);
			} else {
				String clsName = numForm.getClass().getName();

				String msg = String.format("INTERNAL ERROR: Unknown NumberFormat type %s, expected DecimalFormat or compatible", clsName);

				throw new UnsupportedOperationException(msg);
			}
		}

		//StringBuffer work = new StringBuffer();

		//numForm.format(itemTape.item(), work, ZERO_FIELD);

		// formCTX.writer.write(work.toString());
		formCTX.writer.write(numForm.format(itemTape.item()));
		itemTape.right();
	}
}