Mercurial > hg > graal-compiler
comparison graal/com.oracle.truffle.ruby.runtime/src/com/oracle/truffle/ruby/runtime/core/StringFormatter.java @ 13514:0fbee3eb71f0
Ruby: import project.
author | Chris Seaton <chris.seaton@oracle.com> |
---|---|
date | Mon, 06 Jan 2014 17:12:09 +0000 |
parents | |
children |
comparison
equal
deleted
inserted
replaced
13513:64a23ce736a0 | 13514:0fbee3eb71f0 |
---|---|
1 /* | |
2 * Copyright (c) 2013 Oracle and/or its affiliates. All rights reserved. This | |
3 * code is released under a tri EPL/GPL/LGPL license. You can use it, | |
4 * redistribute it and/or modify it under the terms of the: | |
5 * | |
6 * Eclipse Public License version 1.0 | |
7 * GNU General Public License version 2 | |
8 * GNU Lesser General Public License version 2.1 | |
9 */ | |
10 package com.oracle.truffle.ruby.runtime.core; | |
11 | |
12 import java.io.*; | |
13 import java.util.*; | |
14 | |
15 import com.oracle.truffle.ruby.runtime.core.array.*; | |
16 | |
17 public class StringFormatter { | |
18 | |
19 public static String format(String format, List<Object> values) { | |
20 final ByteArrayOutputStream byteArray = new ByteArrayOutputStream(); | |
21 final PrintStream printStream = new PrintStream(byteArray); | |
22 | |
23 format(printStream, format, values); | |
24 | |
25 return byteArray.toString(); | |
26 } | |
27 | |
28 public static void format(PrintStream stream, String format, List<Object> values) { | |
29 /* | |
30 * See http://www.ruby-doc.org/core-1.9.3/Kernel.html#method-i-sprintf. | |
31 * | |
32 * At the moment we just do the basics that we need. We will need a proper lexer later on. | |
33 * Or better than that we could compile to Truffle nodes if the format string is constant! I | |
34 * don't think we can easily translate to Java's format syntax, otherwise JRuby would do | |
35 * that and they don't. | |
36 */ | |
37 | |
38 // I'm not using a for loop, because Checkstyle won't let me modify the control variable | |
39 | |
40 int n = 0; | |
41 int v = 0; | |
42 | |
43 while (n < format.length()) { | |
44 final char c = format.charAt(n); | |
45 n++; | |
46 | |
47 if (c == '%') { | |
48 // %[flags][width][.precision]type | |
49 | |
50 final String flagChars = "0"; | |
51 | |
52 boolean zeroPad = false; | |
53 | |
54 while (n < format.length() && flagChars.indexOf(format.charAt(n)) != -1) { | |
55 switch (format.charAt(n)) { | |
56 case '0': | |
57 zeroPad = true; | |
58 break; | |
59 } | |
60 | |
61 n++; | |
62 } | |
63 | |
64 int width; | |
65 | |
66 if (n < format.length() && Character.isDigit(format.charAt(n))) { | |
67 final int widthStart = n; | |
68 | |
69 while (Character.isDigit(format.charAt(n))) { | |
70 n++; | |
71 } | |
72 | |
73 width = Integer.parseInt(format.substring(widthStart, n)); | |
74 } else { | |
75 width = 0; | |
76 } | |
77 | |
78 int precision; | |
79 | |
80 if (format.charAt(n) == '.') { | |
81 n++; | |
82 | |
83 final int precisionStart = n; | |
84 | |
85 while (Character.isDigit(format.charAt(n))) { | |
86 n++; | |
87 } | |
88 | |
89 precision = Integer.parseInt(format.substring(precisionStart, n)); | |
90 } else { | |
91 precision = 5; | |
92 } | |
93 | |
94 final char type = format.charAt(n); | |
95 n++; | |
96 | |
97 final StringBuilder formatBuilder = new StringBuilder(); | |
98 | |
99 formatBuilder.append("%"); | |
100 | |
101 if (width > 0) { | |
102 if (zeroPad) { | |
103 formatBuilder.append("0"); | |
104 } | |
105 | |
106 formatBuilder.append(width); | |
107 } | |
108 | |
109 switch (type) { | |
110 case 'd': { | |
111 formatBuilder.append("d"); | |
112 final int value = GeneralConversions.toFixnum(values.get(v)); | |
113 stream.printf(formatBuilder.toString(), value); | |
114 break; | |
115 } | |
116 | |
117 case 'f': { | |
118 formatBuilder.append("."); | |
119 formatBuilder.append(precision); | |
120 formatBuilder.append("f"); | |
121 final double value = GeneralConversions.toFloat(values.get(v)); | |
122 stream.printf(formatBuilder.toString(), value); | |
123 break; | |
124 } | |
125 | |
126 default: | |
127 throw new RuntimeException("Kernel#sprintf error"); | |
128 } | |
129 | |
130 v++; | |
131 } else { | |
132 stream.print(c); | |
133 } | |
134 } | |
135 } | |
136 | |
137 public static void formatPuts(PrintStream stream, List<Object> args) { | |
138 if (args.size() > 0) { | |
139 formatPutsInner(stream, args); | |
140 } else { | |
141 stream.println(); | |
142 } | |
143 } | |
144 | |
145 public static void formatPutsInner(PrintStream stream, List<Object> args) { | |
146 if (args.size() > 0) { | |
147 for (Object arg : args) { | |
148 if (arg instanceof RubyArray) { | |
149 final RubyArray array = (RubyArray) arg; | |
150 formatPutsInner(stream, array.asList()); | |
151 } else { | |
152 stream.println(arg); | |
153 } | |
154 } | |
155 } | |
156 } | |
157 } |