1245803Stheraven/*-
2245803Stheraven * Copyright (c) 2013 David Chisnall
3245803Stheraven * All rights reserved.
4245803Stheraven *
5245803Stheraven * This software was developed by SRI International and the University of
6245803Stheraven * Cambridge Computer Laboratory under DARPA/AFRL contract (FA8750-10-C-0237)
7245803Stheraven * ("CTSRD"), as part of the DARPA CRASH research programme.
8245803Stheraven *
9245803Stheraven * Redistribution and use in source and binary forms, with or without
10245803Stheraven * modification, are permitted provided that the following conditions
11245803Stheraven * are met:
12245803Stheraven * 1. Redistributions of source code must retain the above copyright
13245803Stheraven *    notice, this list of conditions and the following disclaimer.
14245803Stheraven * 2. Redistributions in binary form must reproduce the above copyright
15245803Stheraven *    notice, this list of conditions and the following disclaimer in the
16245803Stheraven *    documentation and/or other materials provided with the distribution.
17245803Stheraven *
18245803Stheraven * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
19245803Stheraven * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
20245803Stheraven * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
21245803Stheraven * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
22245803Stheraven * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
23245803Stheraven * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
24245803Stheraven * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
25245803Stheraven * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
26245803Stheraven * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
27245803Stheraven * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
28245803Stheraven * SUCH DAMAGE.
29245803Stheraven *
30245803Stheraven * $FreeBSD: releng/11.0/usr.bin/dtc/input_buffer.cc 292876 2015-12-29 16:29:42Z theraven $
31245803Stheraven */
32245803Stheraven
33245803Stheraven#include "input_buffer.hh"
34245839Stheraven#include <ctype.h>
35245839Stheraven#include <limits.h>
36245839Stheraven#include <stdint.h>
37245839Stheraven#include <stdio.h>
38245839Stheraven#include <stdlib.h>
39245803Stheraven#include <string.h>
40292876Stheraven#include <functional>
41292876Stheraven#ifndef NDEBUG
42292876Stheraven#include <iostream>
43292876Stheraven#endif
44245803Stheraven
45245839Stheraven
46245803Stheraven#include <sys/stat.h>
47245803Stheraven#include <sys/mman.h>
48245803Stheraven#include <assert.h>
49245803Stheraven
50247006Suqs#ifndef MAP_PREFAULT_READ
51247006Suqs#define MAP_PREFAULT_READ 0
52247006Suqs#endif
53247006Suqs
54245803Stheravennamespace dtc
55245803Stheraven{
56245803Stheravenvoid
57245803Stheraveninput_buffer::skip_spaces()
58245803Stheraven{
59245803Stheraven	if (cursor >= size) { return; }
60245803Stheraven	if (cursor < 0) { return; }
61245803Stheraven	char c = buffer[cursor];
62245803Stheraven	while ((c == ' ') || (c == '\t') || (c == '\n') || (c == '\f')
63245803Stheraven	       || (c == '\v') || (c == '\r'))
64245803Stheraven	{
65245803Stheraven		cursor++;
66245803Stheraven		if (cursor > size)
67245803Stheraven		{
68245803Stheraven			c = '\0';
69245803Stheraven		}
70245803Stheraven		else
71245803Stheraven		{
72245803Stheraven			c = buffer[cursor];
73245803Stheraven		}
74245803Stheraven	}
75245803Stheraven}
76245803Stheraven
77245803Stheraveninput_buffer
78245803Stheraveninput_buffer::buffer_from_offset(int offset, int s)
79245803Stheraven{
80245803Stheraven	if (s == 0)
81245803Stheraven	{
82245803Stheraven		s = size - offset;
83245803Stheraven	}
84245803Stheraven	if (offset > size)
85245803Stheraven	{
86245803Stheraven		return input_buffer();
87245803Stheraven	}
88245803Stheraven	if (s > (size-offset))
89245803Stheraven	{
90245803Stheraven		return input_buffer();
91245803Stheraven	}
92245803Stheraven	return input_buffer(&buffer[offset], s);
93245803Stheraven}
94245803Stheraven
95245803Stheravenbool
96245803Stheraveninput_buffer::consume(const char *str)
97245803Stheraven{
98245803Stheraven	int len = strlen(str);
99245803Stheraven	if (len > size - cursor)
100245803Stheraven	{
101245803Stheraven		return false;
102245803Stheraven	}
103245803Stheraven	else
104245803Stheraven	{
105245803Stheraven		for (int i=0 ; i<len ; ++i)
106245803Stheraven		{
107245803Stheraven			if (str[i] != buffer[cursor + i])
108245803Stheraven			{
109245803Stheraven				return false;
110245803Stheraven			}
111245803Stheraven		}
112245803Stheraven		cursor += len;
113245803Stheraven		return true;
114245803Stheraven	}
115245803Stheraven	return false;
116245803Stheraven}
117245803Stheraven
118245803Stheravenbool
119289935Stheraveninput_buffer::consume_integer(unsigned long long &outInt)
120245803Stheraven{
121245803Stheraven	// The first character must be a digit.  Hex and octal strings
122245803Stheraven	// are prefixed by 0 and 0x, respectively.
123245803Stheraven	if (!isdigit((*this)[0]))
124245803Stheraven	{
125245803Stheraven		return false;
126245803Stheraven	}
127245803Stheraven	char *end=0;
128289935Stheraven	outInt = strtoull(&buffer[cursor], &end, 0);
129245803Stheraven	if (end == &buffer[cursor])
130245803Stheraven	{
131245803Stheraven		return false;
132245803Stheraven	}
133245803Stheraven	cursor = end - buffer;
134245803Stheraven	return true;
135245803Stheraven}
136245803Stheraven
137292876Stheravennamespace {
138292876Stheraven
139292876Stheraven/**
140292876Stheraven * Convenience typedef for the type that we use for all values.
141292876Stheraven */
142292876Stheraventypedef unsigned long long valty;
143292876Stheraven
144292876Stheraven/**
145292876Stheraven * Expression tree currently being parsed.
146292876Stheraven */
147292876Stheravenstruct expression
148292876Stheraven{
149292876Stheraven	/**
150292876Stheraven	 * Evaluate this node, taking into account operator precedence.
151292876Stheraven	 */
152292876Stheraven	virtual valty operator()() = 0;
153292876Stheraven	/**
154292876Stheraven	 * Returns the precedence of this node.  Lower values indicate higher
155292876Stheraven	 * precedence.
156292876Stheraven	 */
157292876Stheraven	virtual int precedence() = 0;
158292876Stheraven	virtual ~expression() {}
159292876Stheraven#ifndef NDEBUG
160292876Stheraven	/**
161292876Stheraven	 * Dumps this expression to `std::cerr`, appending a newline if `nl` is
162292876Stheraven	 * `true`.
163292876Stheraven	 */
164292876Stheraven	void dump(bool nl=false)
165292876Stheraven	{
166292876Stheraven		if (this == nullptr)
167292876Stheraven		{
168292876Stheraven			std::cerr << "{nullptr}\n";
169292876Stheraven			return;
170292876Stheraven		}
171292876Stheraven		dump_impl();
172292876Stheraven		if (nl)
173292876Stheraven		{
174292876Stheraven			std::cerr << '\n';
175292876Stheraven		}
176292876Stheraven	}
177292876Stheraven	private:
178292876Stheraven	/**
179292876Stheraven	 * Method that sublcasses override to implement the behaviour of `dump()`.
180292876Stheraven	 */
181292876Stheraven	virtual void dump_impl() = 0;
182292876Stheraven#endif
183292876Stheraven};
184292876Stheraven
185292876Stheraven/**
186292876Stheraven * Expression wrapping a single integer.  Leaf nodes in the expression tree.
187292876Stheraven */
188292876Stheravenclass terminal_expr : public expression
189292876Stheraven{
190292876Stheraven	/**
191292876Stheraven	 * The value that this wraps.
192292876Stheraven	 */
193292876Stheraven	valty val;
194292876Stheraven	/**
195292876Stheraven	 * Evaluate.  Trivially returns the value that this class wraps.
196292876Stheraven	 */
197292876Stheraven	valty operator()() override
198292876Stheraven	{
199292876Stheraven		return val;
200292876Stheraven	}
201292876Stheraven	int precedence() override
202292876Stheraven	{
203292876Stheraven		return 0;
204292876Stheraven	}
205292876Stheraven	public:
206292876Stheraven	/**
207292876Stheraven	 * Constructor.
208292876Stheraven	 */
209292876Stheraven	terminal_expr(valty v) : val(v) {}
210292876Stheraven#ifndef NDEBUG
211292876Stheraven	void dump_impl() override { std::cerr << val; }
212292876Stheraven#endif
213292876Stheraven};
214292876Stheraven
215292876Stheraven/**
216292876Stheraven * Parenthetical expression.  Exists to make the contents opaque.
217292876Stheraven */
218292876Stheravenstruct paren_expression : public expression
219292876Stheraven{
220292876Stheraven	/**
221292876Stheraven	 * The expression within the parentheses.
222292876Stheraven	 */
223292876Stheraven	expression_ptr subexpr;
224292876Stheraven	/**
225292876Stheraven	 * Constructor.  Takes the child expression as the only argument.
226292876Stheraven	 */
227292876Stheraven	paren_expression(expression_ptr p) : subexpr(std::move(p)) {}
228292876Stheraven	int precedence() override
229292876Stheraven	{
230292876Stheraven		return 0;
231292876Stheraven	}
232292876Stheraven	/**
233292876Stheraven	 * Evaluate - just forwards to the underlying expression.
234292876Stheraven	 */
235292876Stheraven	valty operator()() override
236292876Stheraven	{
237292876Stheraven		return (*subexpr)();
238292876Stheraven	}
239292876Stheraven#ifndef NDEBUG
240292876Stheraven	void dump_impl() override
241292876Stheraven	{
242292876Stheraven		std::cerr << " (";
243292876Stheraven		subexpr->dump();
244292876Stheraven		std::cerr << ") ";
245292876Stheraven	}
246292876Stheraven#endif
247292876Stheraven};
248292876Stheraven
249292876Stheraven/**
250292876Stheraven * Template class for unary operators.  The `OpChar` template parameter is
251292876Stheraven * solely for debugging and makes it easy to print the expression.  The `Op`
252292876Stheraven * template parameter is a function object that implements the operator that
253292876Stheraven * this class provides.  Most of these are provided by the `<functional>`
254292876Stheraven * header.
255292876Stheraven */
256292876Stheraventemplate<char OpChar, class Op>
257292876Stheravenclass unary_operator : public expression
258292876Stheraven{
259292876Stheraven	/**
260292876Stheraven	 * The subexpression for this unary operator.
261292876Stheraven	 */
262292876Stheraven	expression_ptr subexpr;
263292876Stheraven	valty operator()() override
264292876Stheraven	{
265292876Stheraven		Op op;
266292876Stheraven		return op((*subexpr)());
267292876Stheraven	}
268292876Stheraven	/**
269292876Stheraven	 * All unary operators have the same precedence.  They are all evaluated
270292876Stheraven	 * before binary expressions, but after parentheses.
271292876Stheraven	 */
272292876Stheraven	int precedence() override
273292876Stheraven	{
274292876Stheraven		return 3;
275292876Stheraven	}
276292876Stheraven	public:
277292876Stheraven	unary_operator(expression_ptr p) : subexpr(std::move(p)) {}
278292876Stheraven#ifndef NDEBUG
279292876Stheraven	void dump_impl() override
280292876Stheraven	{
281292876Stheraven		std::cerr << OpChar;
282292876Stheraven		subexpr->dump();
283292876Stheraven	}
284292876Stheraven#endif
285292876Stheraven};
286292876Stheraven
287292876Stheraven/**
288292876Stheraven * Abstract base class for binary operators.  Allows the tree to be modified
289292876Stheraven * without knowing what the operations actually are.
290292876Stheraven */
291292876Stheravenstruct binary_operator_base : public expression
292292876Stheraven{
293292876Stheraven	/**
294292876Stheraven	 * The left side of the expression.
295292876Stheraven	 */
296292876Stheraven	expression_ptr lhs;
297292876Stheraven	/**
298292876Stheraven	 * The right side of the expression.
299292876Stheraven	 */
300292876Stheraven	expression_ptr rhs;
301292876Stheraven	/**
302292876Stheraven	 * Insert a node somewhere down the path of left children, until it would
303292876Stheraven	 * be preempting something that should execute first.
304292876Stheraven	 */
305292876Stheraven	void insert_left(binary_operator_base *new_left)
306292876Stheraven	{
307292876Stheraven		if (lhs->precedence() < new_left->precedence())
308292876Stheraven		{
309292876Stheraven			new_left->rhs = std::move(lhs);
310292876Stheraven			lhs.reset(new_left);
311292876Stheraven		}
312292876Stheraven		else
313292876Stheraven		{
314292876Stheraven			static_cast<binary_operator_base*>(lhs.get())->insert_left(new_left);
315292876Stheraven		}
316292876Stheraven	}
317292876Stheraven};
318292876Stheraven
319292876Stheraven/**
320292876Stheraven * Template class for binary operators.  The precedence and the operation are
321292876Stheraven * provided as template parameters.
322292876Stheraven */
323292876Stheraventemplate<int Precedence, class Op>
324292876Stheravenstruct binary_operator : public binary_operator_base
325292876Stheraven{
326292876Stheraven	valty operator()() override
327292876Stheraven	{
328292876Stheraven		Op op;
329292876Stheraven		return op((*lhs)(), (*rhs)());
330292876Stheraven	}
331292876Stheraven	int precedence() override
332292876Stheraven	{
333292876Stheraven		return Precedence;
334292876Stheraven	}
335292876Stheraven#ifdef NDEBUG
336292876Stheraven	/**
337292876Stheraven	 * Constructor.  Takes the name of the operator as an argument, for
338292876Stheraven	 * debugging.  Only stores it in debug mode.
339292876Stheraven	 */
340292876Stheraven	binary_operator(const char *) {}
341292876Stheraven#else
342292876Stheraven	const char *opName;
343292876Stheraven	binary_operator(const char *o) : opName(o) {}
344292876Stheraven	void dump_impl() override
345292876Stheraven	{
346292876Stheraven		lhs->dump();
347292876Stheraven		std::cerr << opName;
348292876Stheraven		rhs->dump();
349292876Stheraven	}
350292876Stheraven#endif
351292876Stheraven};
352292876Stheraven
353292876Stheraven/**
354292876Stheraven * Ternary conditional operators (`cond ? true : false`) are a special case -
355292876Stheraven * there are no other ternary operators.
356292876Stheraven */
357292876Stheravenclass ternary_conditional_operator : public expression
358292876Stheraven{
359292876Stheraven	/**
360292876Stheraven	 * The condition for the clause.
361292876Stheraven	 */
362292876Stheraven	expression_ptr cond;
363292876Stheraven	/**
364292876Stheraven	 * The expression that this evaluates to if the condition is true.
365292876Stheraven	 */
366292876Stheraven	expression_ptr lhs;
367292876Stheraven	/**
368292876Stheraven	 * The expression that this evaluates to if the condition is false.
369292876Stheraven	 */
370292876Stheraven	expression_ptr rhs;
371292876Stheraven	valty operator()() override
372292876Stheraven	{
373292876Stheraven		return (*cond)() ? (*lhs)() : (*rhs)();
374292876Stheraven	}
375292876Stheraven	int precedence() override
376292876Stheraven	{
377292876Stheraven		// The actual precedence of a ternary conditional operator is 15, but
378292876Stheraven		// its associativity is the opposite way around to the other operators,
379292876Stheraven		// so we fudge it slightly.
380292876Stheraven		return 3;
381292876Stheraven	}
382292876Stheraven#ifndef NDEBUG
383292876Stheraven	void dump_impl() override
384292876Stheraven	{
385292876Stheraven		cond->dump();
386292876Stheraven		std::cerr << " ? ";
387292876Stheraven		lhs->dump();
388292876Stheraven		std::cerr << " : ";
389292876Stheraven		rhs->dump();
390292876Stheraven	}
391292876Stheraven#endif
392292876Stheraven	public:
393292876Stheraven	ternary_conditional_operator(expression_ptr c,
394292876Stheraven	                             expression_ptr l,
395292876Stheraven	                             expression_ptr r) :
396292876Stheraven		cond(std::move(c)), lhs(std::move(l)), rhs(std::move(r)) {}
397292876Stheraven};
398292876Stheraven
399292876Stheraventemplate<typename T>
400292876Stheravenstruct lshift
401292876Stheraven{
402292876Stheraven	constexpr T operator()(const T &lhs, const T &rhs) const
403292876Stheraven	{
404292876Stheraven		return lhs << rhs;
405292876Stheraven	}
406292876Stheraven};
407292876Stheraventemplate<typename T>
408292876Stheravenstruct rshift
409292876Stheraven{
410292876Stheraven	constexpr T operator()(const T &lhs, const T &rhs) const
411292876Stheraven	{
412292876Stheraven		return lhs >> rhs;
413292876Stheraven	}
414292876Stheraven};
415292876Stheraventemplate<typename T>
416292876Stheravenstruct unary_plus
417292876Stheraven{
418292876Stheraven	constexpr T operator()(const T &val) const
419292876Stheraven	{
420292876Stheraven		return +val;
421292876Stheraven	}
422292876Stheraven};
423292876Stheraven// TODO: Replace with std::bit_not once we can guarantee C++14 as a baseline.
424292876Stheraventemplate<typename T>
425292876Stheravenstruct bit_not
426292876Stheraven{
427292876Stheraven	constexpr T operator()(const T &val) const
428292876Stheraven	{
429292876Stheraven		return ~val;
430292876Stheraven	}
431292876Stheraven};
432292876Stheraven
433292876Stheraven} // anonymous namespace
434292876Stheraven
435292876Stheraven
436292876Stheravenexpression_ptr input_buffer::parse_binary_expression(expression_ptr lhs)
437292876Stheraven{
438292876Stheraven	next_token();
439292876Stheraven	binary_operator_base *expr = nullptr;
440292876Stheraven	char op = ((*this)[0]);
441292876Stheraven	switch (op)
442292876Stheraven	{
443292876Stheraven		default:
444292876Stheraven			return lhs;
445292876Stheraven		case '+':
446292876Stheraven			expr = new binary_operator<6, std::plus<valty>>("+");
447292876Stheraven			break;
448292876Stheraven		case '-':
449292876Stheraven			expr = new binary_operator<6, std::minus<valty>>("-");
450292876Stheraven			break;
451292876Stheraven		case '%':
452292876Stheraven			expr = new binary_operator<5, std::modulus<valty>>("%");
453292876Stheraven			break;
454292876Stheraven		case '*':
455292876Stheraven			expr = new binary_operator<5, std::multiplies<valty>>("*");
456292876Stheraven			break;
457292876Stheraven		case '/':
458292876Stheraven			expr = new binary_operator<5, std::divides<valty>>("/");
459292876Stheraven			break;
460292876Stheraven		case '<':
461292876Stheraven			cursor++;
462292876Stheraven			switch ((*this)[0])
463292876Stheraven			{
464292876Stheraven				default:
465292876Stheraven					parse_error("Invalid operator");
466292876Stheraven					return nullptr;
467292876Stheraven				case ' ':
468292876Stheraven				case '(':
469292876Stheraven				case '0'...'9':
470292876Stheraven					cursor--;
471292876Stheraven					expr = new binary_operator<8, std::less<valty>>("<");
472292876Stheraven					break;
473292876Stheraven				case '=':
474292876Stheraven					expr = new binary_operator<8, std::less_equal<valty>>("<=");
475292876Stheraven					break;
476292876Stheraven				case '<':
477292876Stheraven					expr = new binary_operator<7, lshift<valty>>("<<");
478292876Stheraven					break;
479292876Stheraven			}
480292876Stheraven			break;
481292876Stheraven		case '>':
482292876Stheraven			cursor++;
483292876Stheraven			switch ((*this)[0])
484292876Stheraven			{
485292876Stheraven				default:
486292876Stheraven					parse_error("Invalid operator");
487292876Stheraven					return nullptr;
488292876Stheraven				case '(':
489292876Stheraven				case ' ':
490292876Stheraven				case '0'...'9':
491292876Stheraven					cursor--;
492292876Stheraven					expr = new binary_operator<8, std::greater<valty>>(">");
493292876Stheraven					break;
494292876Stheraven				case '=':
495292876Stheraven					expr = new binary_operator<8, std::greater_equal<valty>>(">=");
496292876Stheraven					break;
497292876Stheraven				case '>':
498292876Stheraven					expr = new binary_operator<7, rshift<valty>>(">>");
499292876Stheraven					break;
500292876Stheraven					return lhs;
501292876Stheraven			}
502292876Stheraven			break;
503292876Stheraven		case '=':
504292876Stheraven			if ((*this)[1] != '=')
505292876Stheraven			{
506292876Stheraven				parse_error("Invalid operator");
507292876Stheraven				return nullptr;
508292876Stheraven			}
509292876Stheraven			consume('=');
510292876Stheraven			expr = new binary_operator<9, std::equal_to<valty>>("==");
511292876Stheraven			break;
512292876Stheraven		case '!':
513292876Stheraven			if ((*this)[1] != '=')
514292876Stheraven			{
515292876Stheraven				parse_error("Invalid operator");
516292876Stheraven				return nullptr;
517292876Stheraven			}
518292876Stheraven			cursor++;
519292876Stheraven			expr = new binary_operator<9, std::not_equal_to<valty>>("!=");
520292876Stheraven			break;
521292876Stheraven		case '&':
522292876Stheraven			if ((*this)[1] == '&')
523292876Stheraven			{
524292876Stheraven				expr = new binary_operator<13, std::logical_and<valty>>("&&");
525292876Stheraven			}
526292876Stheraven			else
527292876Stheraven			{
528292876Stheraven				expr = new binary_operator<10, std::bit_and<valty>>("&");
529292876Stheraven			}
530292876Stheraven			break;
531292876Stheraven		case '|':
532292876Stheraven			if ((*this)[1] == '|')
533292876Stheraven			{
534292876Stheraven				expr = new binary_operator<12, std::logical_or<valty>>("||");
535292876Stheraven			}
536292876Stheraven			else
537292876Stheraven			{
538292876Stheraven				expr = new binary_operator<14, std::bit_or<valty>>("|");
539292876Stheraven			}
540292876Stheraven			break;
541292876Stheraven		case '?':
542292876Stheraven		{
543292876Stheraven			consume('?');
544292876Stheraven			expression_ptr true_case = parse_expression();
545292876Stheraven			next_token();
546292876Stheraven			if (!true_case || !consume(':'))
547292876Stheraven			{
548292876Stheraven				parse_error("Expected : in ternary conditional operator");
549292876Stheraven				return nullptr;
550292876Stheraven			}
551292876Stheraven			expression_ptr false_case = parse_expression();
552292876Stheraven			if (!false_case)
553292876Stheraven			{
554292876Stheraven				parse_error("Expected false condition for ternary operator");
555292876Stheraven				return nullptr;
556292876Stheraven			}
557292876Stheraven			return expression_ptr(new ternary_conditional_operator(std::move(lhs),
558292876Stheraven						std::move(true_case), std::move(false_case)));
559292876Stheraven		}
560292876Stheraven	}
561292876Stheraven	cursor++;
562292876Stheraven	next_token();
563292876Stheraven	expression_ptr e(expr);
564292876Stheraven	expression_ptr rhs(parse_expression());
565292876Stheraven	if (!rhs)
566292876Stheraven	{
567292876Stheraven		return nullptr;
568292876Stheraven	}
569292876Stheraven	expr->lhs = std::move(lhs);
570292876Stheraven	if (rhs->precedence() < expr->precedence())
571292876Stheraven	{
572292876Stheraven		expr->rhs = std::move(rhs);
573292876Stheraven	}
574292876Stheraven	else
575292876Stheraven	{
576292876Stheraven		// If we're a normal left-to-right expression, then we need to insert
577292876Stheraven		// this as the far-left child node of the rhs expression
578292876Stheraven		binary_operator_base *rhs_op =
579292876Stheraven			static_cast<binary_operator_base*>(rhs.get());
580292876Stheraven		rhs_op->insert_left(expr);
581292876Stheraven		e.release();
582292876Stheraven		return rhs;
583292876Stheraven	}
584292876Stheraven	return e;
585292876Stheraven}
586292876Stheraven
587292876Stheravenexpression_ptr input_buffer::parse_expression(bool stopAtParen)
588292876Stheraven{
589292876Stheraven	next_token();
590292876Stheraven	unsigned long long leftVal;
591292876Stheraven	expression_ptr lhs;
592292876Stheraven	switch ((*this)[0])
593292876Stheraven	{
594292876Stheraven		case '0'...'9':
595292876Stheraven			if (!consume_integer(leftVal))
596292876Stheraven			{
597292876Stheraven				return nullptr;
598292876Stheraven			}
599292876Stheraven			lhs.reset(new terminal_expr(leftVal));
600292876Stheraven			break;
601292876Stheraven		case '(':
602292876Stheraven		{
603292876Stheraven			consume('(');
604292876Stheraven			expression_ptr &&subexpr = parse_expression();
605292876Stheraven			if (!subexpr)
606292876Stheraven			{
607292876Stheraven				return nullptr;
608292876Stheraven			}
609292876Stheraven			lhs.reset(new paren_expression(std::move(subexpr)));
610292876Stheraven			if (!consume(')'))
611292876Stheraven			{
612292876Stheraven				return nullptr;
613292876Stheraven			}
614292876Stheraven			if (stopAtParen)
615292876Stheraven			{
616292876Stheraven				return lhs;
617292876Stheraven			}
618292876Stheraven			break;
619292876Stheraven		}
620292876Stheraven		case '+':
621292876Stheraven		{
622292876Stheraven			consume('+');
623292876Stheraven			expression_ptr &&subexpr = parse_expression();
624292876Stheraven			if (!subexpr)
625292876Stheraven			{
626292876Stheraven				return nullptr;
627292876Stheraven			}
628292876Stheraven			lhs.reset(new unary_operator<'+', unary_plus<valty>>(std::move(subexpr)));
629292876Stheraven			break;
630292876Stheraven		}
631292876Stheraven		case '-':
632292876Stheraven		{
633292876Stheraven			consume('-');
634292876Stheraven			expression_ptr &&subexpr = parse_expression();
635292876Stheraven			if (!subexpr)
636292876Stheraven			{
637292876Stheraven				return nullptr;
638292876Stheraven			}
639292876Stheraven			lhs.reset(new unary_operator<'-', std::negate<valty>>(std::move(subexpr)));
640292876Stheraven			break;
641292876Stheraven		}
642292876Stheraven		case '!':
643292876Stheraven		{
644292876Stheraven			consume('!');
645292876Stheraven			expression_ptr &&subexpr = parse_expression();
646292876Stheraven			if (!subexpr)
647292876Stheraven			{
648292876Stheraven				return nullptr;
649292876Stheraven			}
650292876Stheraven			lhs.reset(new unary_operator<'!', std::logical_not<valty>>(std::move(subexpr)));
651292876Stheraven			break;
652292876Stheraven		}
653292876Stheraven		case '~':
654292876Stheraven		{
655292876Stheraven			consume('~');
656292876Stheraven			expression_ptr &&subexpr = parse_expression();
657292876Stheraven			if (!subexpr)
658292876Stheraven			{
659292876Stheraven				return nullptr;
660292876Stheraven			}
661292876Stheraven			lhs.reset(new unary_operator<'~', bit_not<valty>>(std::move(subexpr)));
662292876Stheraven			break;
663292876Stheraven		}
664292876Stheraven	}
665292876Stheraven	if (!lhs)
666292876Stheraven	{
667292876Stheraven		return nullptr;
668292876Stheraven	}
669292876Stheraven	return parse_binary_expression(std::move(lhs));
670292876Stheraven}
671292876Stheraven
672245803Stheravenbool
673292876Stheraveninput_buffer::consume_integer_expression(unsigned long long &outInt)
674292876Stheraven{
675292876Stheraven	switch ((*this)[0])
676292876Stheraven	{
677292876Stheraven		case '(':
678292876Stheraven		{
679292876Stheraven			expression_ptr e(parse_expression(true));
680292876Stheraven			if (!e)
681292876Stheraven			{
682292876Stheraven				return false;
683292876Stheraven			}
684292876Stheraven			outInt = (*e)();
685292876Stheraven			return true;
686292876Stheraven		}
687292876Stheraven		case '0'...'9':
688292876Stheraven			return consume_integer(outInt);
689292876Stheraven		default:
690292876Stheraven			return false;
691292876Stheraven	}
692292876Stheraven}
693292876Stheraven
694292876Stheravenbool
695245803Stheraveninput_buffer::consume_hex_byte(uint8_t &outByte)
696245803Stheraven{
697245803Stheraven	if (!ishexdigit((*this)[0]) && !ishexdigit((*this)[1]))
698245803Stheraven	{
699245803Stheraven		return false;
700245803Stheraven	}
701245803Stheraven	outByte = (digittoint((*this)[0]) << 4) | digittoint((*this)[1]);
702245803Stheraven	cursor += 2;
703245803Stheraven	return true;
704245803Stheraven}
705245803Stheraven
706245803Stheraveninput_buffer&
707245803Stheraveninput_buffer::next_token()
708245803Stheraven{
709245803Stheraven	int start;
710245803Stheraven	do {
711245803Stheraven		start = cursor;
712245803Stheraven		skip_spaces();
713245803Stheraven		// Parse /* comments
714267318Srpaulo		if ((*this)[0] == '/' && (*this)[1] == '*')
715245803Stheraven		{
716245803Stheraven			// eat the start of the comment
717245803Stheraven			++(*this);
718245803Stheraven			++(*this);
719245803Stheraven			do {
720245803Stheraven				// Find the ending * of */
721245803Stheraven				while ((**this != '\0') && (**this != '*'))
722245803Stheraven				{
723245803Stheraven					++(*this);
724245803Stheraven				}
725245803Stheraven				// Eat the *
726245803Stheraven				++(*this);
727245803Stheraven			} while ((**this != '\0') && (**this != '/'));
728245803Stheraven			// Eat the /
729245803Stheraven			++(*this);
730245803Stheraven		}
731289935Stheraven		// Parse // comments
732289935Stheraven		if (((*this)[0] == '/' && (*this)[1] == '/'))
733245803Stheraven		{
734245803Stheraven			// eat the start of the comment
735245803Stheraven			++(*this);
736245803Stheraven			++(*this);
737267318Srpaulo			// Find the ending of the line
738245803Stheraven			while (**this != '\n')
739245803Stheraven			{
740245803Stheraven				++(*this);
741245803Stheraven			}
742245803Stheraven			// Eat the \n
743245803Stheraven			++(*this);
744245803Stheraven		}
745245803Stheraven	} while (start != cursor);
746245803Stheraven	return *this;
747245803Stheraven}
748245803Stheraven
749245803Stheravenvoid
750245803Stheraveninput_buffer::parse_error(const char *msg)
751245803Stheraven{
752245803Stheraven	int line_count = 1;
753245803Stheraven	int line_start = 0;
754245803Stheraven	int line_end = cursor;
755245803Stheraven	for (int i=cursor ; i>0 ; --i)
756245803Stheraven	{
757245803Stheraven		if (buffer[i] == '\n')
758245803Stheraven		{
759245803Stheraven			line_count++;
760245803Stheraven			if (line_start == 0)
761245803Stheraven			{
762245803Stheraven				line_start = i+1;
763245803Stheraven			}
764245803Stheraven		}
765245803Stheraven	}
766245803Stheraven	for (int i=cursor+1 ; i<size ; ++i)
767245803Stheraven	{
768245803Stheraven		if (buffer[i] == '\n')
769245803Stheraven		{
770245803Stheraven			line_end = i;
771245803Stheraven			break;
772245803Stheraven		}
773245803Stheraven	}
774245803Stheraven	fprintf(stderr, "Error on line %d: %s\n", line_count, msg);
775245803Stheraven	fwrite(&buffer[line_start], line_end-line_start, 1, stderr);
776245803Stheraven	putc('\n', stderr);
777245803Stheraven	for (int i=0 ; i<(cursor-line_start) ; ++i)
778245803Stheraven	{
779254327Stheraven		char c = (buffer[i+line_start] == '\t') ? '\t' : ' ';
780254327Stheraven		putc(c, stderr);
781245803Stheraven	}
782245803Stheraven	putc('^', stderr);
783245803Stheraven	putc('\n', stderr);
784245803Stheraven}
785292876Stheraven#ifndef NDEBUG
786245803Stheravenvoid
787245803Stheraveninput_buffer::dump()
788245803Stheraven{
789245803Stheraven	fprintf(stderr, "Current cursor: %d\n", cursor);
790245803Stheraven	fwrite(&buffer[cursor], size-cursor, 1, stderr);
791245803Stheraven}
792292876Stheraven#endif
793245803Stheraven
794245803Stheravenmmap_input_buffer::mmap_input_buffer(int fd) : input_buffer(0, 0)
795245803Stheraven{
796245803Stheraven	struct stat sb;
797245803Stheraven	if (fstat(fd, &sb))
798245803Stheraven	{
799245803Stheraven		perror("Failed to stat file");
800245803Stheraven	}
801245803Stheraven	size = sb.st_size;
802289935Stheraven	buffer = (const char*)mmap(0, size, PROT_READ, MAP_PRIVATE |
803289935Stheraven			MAP_PREFAULT_READ, fd, 0);
804289935Stheraven	if (buffer == MAP_FAILED)
805245803Stheraven	{
806245803Stheraven		perror("Failed to mmap file");
807289935Stheraven		exit(EXIT_FAILURE);
808245803Stheraven	}
809245803Stheraven}
810245803Stheraven
811245803Stheravenmmap_input_buffer::~mmap_input_buffer()
812245803Stheraven{
813245803Stheraven	if (buffer != 0)
814245803Stheraven	{
815245803Stheraven		munmap((void*)buffer, size);
816245803Stheraven	}
817245803Stheraven}
818245803Stheraven
819245803Stheravenstream_input_buffer::stream_input_buffer() : input_buffer(0, 0)
820245803Stheraven{
821245803Stheraven	int c;
822245803Stheraven	while ((c = fgetc(stdin)) != EOF)
823245803Stheraven	{
824245803Stheraven		b.push_back(c);
825245803Stheraven	}
826245803Stheraven	buffer = b.data();
827245803Stheraven	size = b.size();
828245803Stheraven}
829245803Stheraven
830245803Stheraven} // namespace dtc
831245803Stheraven
832