Пример #1
0
ExpPtr parseCond (Lexer& lex)
{
	Span spStart, spEnd;
	ExpPtr expCond, expThen, expElse;
	bool blockRequired = true;

	spStart = lex.eat(tIf).span;

	expCond = parseExp(lex);

	if (lex.current() == tThen)
	{
		lex.advance();
		blockRequired = false;
	}

	expThen = blockRequired ? 
				parseBlock(lex) :
				parseExp(lex);

	if (lex.current() == tElse)
	{
		lex.advance();
		if (blockRequired)
		{
			// if {} else {}
			// if {} else if ...
			
			if (lex.current() != tIf)
				lex.expect(tLCurl);
			expElse = parseExp(lex);
		}
		else
			expElse = parseExp(lex);

		spEnd = expElse->span;
	}
	else if (!blockRequired)
		lex.expect(tElse);
	else
	{
		auto expUnit = Exp::make(eTuple, {}, spStart);
		expThen->subexps.push_back(expUnit);
		expElse = expUnit; // no else => unit (zero tuple)
		spEnd = expThen->span;
	}

	return Exp::make(eCond, { expCond, expThen, expElse }, spStart + spEnd);
}
Пример #2
0
GlobProto parseToplevel (Lexer& lex)
{
	GlobProto res;
	while (parseToplevel(lex, res)) ;
	lex.expect(tEOF);
	return res;
}
Пример #3
0
void parseBlockExp (Lexer& lex, ExpList& list)
{
	switch (lex.current().tok)
	{
	case tSemicolon:
		lex.advance();
		break;
	case tLet:
		list.push_back(parseLet(lex));
		lex.eat(tSemicolon);
		break;
	case tLCurl:
		list.push_back(parseBlock(lex));
		break;
	case tIf:
		list.push_back(parseCond(lex));
		break;
	case tLoop:
		list.push_back(parseLoop(lex));
		break;
	case tFor:
		list.push_back(parseFor(lex));
		break;

	// everthing else does
	default:
		list.push_back(parseAssign(lex, parseExp(lex)));
		if (lex.current() != tSemicolon)
			lex.expect(tRCurl);
		else
			lex.eat(tSemicolon);
		break;
	}
}
Пример #4
0
ExpPtr parseAssign (Lexer& lex, ExpPtr left)
{
	if (lex.current() != tEqual)
		return left;

	lex.eat(tEqual);

	auto right = parseExp(lex);

	lex.expect(tSemicolon);

	return Exp::make(eAssign, { left, right }, left->span + right->span);
}
Пример #5
0
TyPtr parseType (Lexer& lex, Span& sp)
{
	switch (lex.current().tok)
	{
	case tLambda:
		return parseTypePoly(lex, sp);
	case tLBrack:
		return parseTypeList(lex, sp);
	case tLParen:
		return parseTypeTuple(lex, sp);
	case tIdent:
		return parseTypeConcrete(lex, sp);

	case tWildcard:
		sp = lex.current().span;
		lex.advance();
		return Ty::makeWildcard();

	default:
		lex.expect("type");
		return nullptr;
	}
}
Пример #6
0
SigPtr parseSig (Lexer& lex, bool anything)
{
	auto res = std::make_shared<Sig>();
	
	// sig := (<var> (',' <var>)*)?

	for (;; anything = true)
	{
		if (anything)
			lex.expect(tIdent);
		else if (lex.current() != tIdent)
			break;

		parseVar(lex, res);

		if (lex.current() == tComma)
			lex.advance();
		else
			break;
	}

	return res;
}
Пример #7
0
ExpPtr parseExp (Lexer& lex)
{
	Span spStart, spEnd;
	ExpList vals;
	ExpPtr e;
	Token tok;

	e = parseTerm(lex);
	vals.push_back(e);
	spStart = spEnd = e->span;

	while (lex.current() == tIdent)
		if (lex.current().isOperator())
		{
			// <op>
			tok = lex.advance();
			e = Exp::make(eVar, tok.str, bool(true), {}, tok.span);
			vals.push_back(e);

			// <term>
			e = parseTerm(lex);
			vals.push_back(e);

			spEnd = e->span;
		}
		else
			lex.expect("operator");

	if (vals.size() == 1)
		return vals[0];
//	else if (vals.size() == 3)
//		return Exp::make(eCall, { vals[1], vals[0], vals[2] },
//							spStart + spEnd);
	else
		return Exp::make(eInfix, vals, spStart + spEnd);
}