Example #1
0
ExpPtr parseLambda (Lexer& lex)
{
	Span spStart, spEnd;
	SigPtr sig;
	ExpPtr body;

	spStart = lex.current().span;

	if (lex.current() == tFunc)
	{
		lex.advance();
		sig = parseSigParens(lex);
		body = parseBlock(lex);
	}
	else
	{
		lex.eat(tLambda);
		sig = parseSig(lex, true);
		lex.eat(tArrow);
		body = parseExp(lex);
	}
	spEnd = body->span;

	return Exp::make(eLambda, sig->toSigType(), "", { body }, spStart + spEnd);
}
Example #2
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;
	}
}
Example #3
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);
}
Example #4
0
TyPtr parseTypeConcrete (Lexer& lex, Span& sp)
{
	Span spStart, spEnd;

	std::vector<TyPtr> sub;
	spStart = lex.current().span;
	auto kind = lex.eat(tIdent).str;

	if (lex.current() == tLParen)
		parseTypeTupleRaw(lex, sub, spEnd);

	sp = spStart + spEnd;

	return Ty::makeConcrete(kind, sub);
}
Example #5
0
ExpPtr parseFor (Lexer& lex)
{
	Span spStart, spEnd;
	ExpPtr val1, val2, body;

	spStart = lex.eat(tFor).span;

	auto var = lex.eat(tIdent).str;
	lex.eat(tColon);

	val1 = parseExp(lex);
	if (lex.current() == tArrow)
	{
		lex.advance();
		val2 = parseExp(lex);
	}
	else
		val2 = nullptr;

	body = parseBlock(lex);
	spEnd = body->span;

	if (val2 == nullptr)
		return Exp::make(eForEach, var,
				{ val1, body }, spStart + spEnd);
	else
		return Exp::make(eForRange, var,
				{ val1, val2, body }, spStart + spEnd);
}
Example #6
0
void parseVar (Lexer& lex, std::string& name, TyPtr& ty, Span& sp)
{
	sp = lex.current().span;
	name = lex.eat(tIdent).str;

	if (lex.current() == tColon)
	{
		Span spEnd;

		lex.advance();
		ty = parseType(lex, spEnd);

		sp = sp + spEnd;
	}
	else
		ty = Ty::makeWildcard();
}
Example #7
0
ImportDecl parseImportDecl (Lexer& lex)
{
	Span spStart, spEnd;

	spStart = lex.eat(tImport).span;
	auto nameTok = lex.eat(tIdent, tString);
	auto name = nameTok.str;
	spEnd = nameTok.span;

	return ImportDecl
		{
			.isPublic = false,
			.name = name,
			.span = spStart + spEnd
		};
}
FuncDecl parseFuncDecl (Lexer& lex)
{
	Span spStart, spEnd;

	spStart = lex.eat(tFunc).span;
	auto name = lex.eat(tIdent).str;
	auto sig = parseSigParens(lex);
	
	ExpPtr body;
/*	if (lex.current() == tEqual)
	{
		lex.advance();
		body = parseExp(lex);
	}
	else */
		body = parseBlock(lex);

	spEnd = sig->span;

	return FuncDecl
		{
			.isPublic = false,
			.name = name,
			.signature = sig,
			.body = body,
			.span = spStart + spEnd
		};
}

static FuncDecl parseConstructor (Lexer& lex)
{
	Span spStart, spEnd;
	FuncDecl result;

	result.name = lex.current().str;
	spStart = lex.eat(tIdent).span;
	result.signature = parseSigParens(lex);
	spEnd = result.signature->span;
	result.span = spStart + spEnd;
	result.body = nullptr;
	return result;
}
Example #8
0
static void parseTypeTupleRaw (Lexer& lex, std::vector<TyPtr>& out, Span& sp)
{
	Span spStart, spEnd;

	spStart = lex.eat(tLParen).span;
	while (lex.current() != tRParen)
	{
		out.push_back(parseType(lex, spEnd));

		if (lex.current() == tComma)
			lex.advance();
		else
			break;
	}
	spEnd = lex.eat(tRParen).span;

	sp = spStart + spEnd;
}
Example #9
0
ExpPtr parseList (Lexer& lex)
{
	Span spStart, spEnd;
	ExpList vals;

	spStart = lex.eat(tLBrack).span;
	while (lex.current() != tRBrack)
	{
		vals.push_back(parseExp(lex));

		if (lex.current() == tComma)
			lex.advance();
		else
			break;
	}
	spEnd = lex.eat(tRBrack).span;

	return Exp::make(eList, std::move(vals), spStart + spEnd);
}
Example #10
0
TyPtr parseTypePoly (Lexer& lex, Span& sp)
{
	Span spStart, spEnd;

	spStart = lex.eat(tLambda).span;
	spEnd = lex.current().span;
	auto name = lex.eat(tIdent).str;

	sp = spStart + spEnd;
	return Ty::makePoly(name);
}
Example #11
0
void parsePublic (Lexer& lex, GlobProto& proto)
{
	Span span = lex.eat(tPub).span;

	if (lex.current() == tFunc)
	{
		auto fn = parseFuncDecl(lex);
		fn.isPublic = true;
		fn.span = span + fn.span;
		proto.funcs.push_back(fn);
	}
	else if (lex.current() == tImport)
	{
		auto imp = parseImportDecl(lex);
		imp.isPublic = true;
		imp.span = span + imp.span;
		proto.imports.push_back(imp);
	}
	else
		lex.unexpect();
}
Example #12
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);
}
Example #13
0
ExpPtr parseTermPrefix (Lexer& lex)
{
	Token tok = lex.current();

	switch (tok.tok)
	{
	case tNumberInt:
		tok = lex.advance();
		return Exp::make(eInt, tok.valueInt, {}, tok.span);

	case tNumberReal:
		tok = lex.advance();
		return Exp::make(eReal, tok.valueReal, {}, tok.span);

	case tString:
		tok = lex.advance();
		return Exp::make(eString, tok.str, {}, tok.span);

	case tTrue:
	case tFalse:
		tok = lex.advance();
		return Exp::make(eBool, tok == tTrue, {}, tok.span);

	case tIdent:
		tok = lex.advance();
		return Exp::make(eVar, tok.str, bool(true), {}, tok.span);

	case tLParen:
		return parseTuple(lex);
	case tIf:
		return parseCond(lex);
	case tLCurl:
		return parseBlock(lex);
	case tLBrack:
		return parseList(lex);

	case tFunc: case tLambda:
		return parseLambda(lex);

	case tiMake:  return parseiMake(lex);
	case tiGet:   return parseiGet(lex);
	case tiPut:   return parseiPut(lex);
	case tiCall:  return parseiCall(lex);

	default:
		//lex.expect("term");
		lex.unexpect();
		return nullptr;
	}
}
Example #14
0
ExpPtr parseBlock (Lexer& lex)
{
	Span spStart, spEnd;
	ExpList exps;

	spStart = lex.eat(tLCurl).span;

	while (lex.current() != tRCurl)
		parseBlockExp(lex, exps);

	spEnd = lex.eat(tRCurl).span;

	return Exp::make(eBlock, exps, spStart + spEnd);
}
Example #15
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;
}
Example #16
0
ExpPtr parseTuple (Lexer& lex)
{
	ExpList exps;
	ExpPtr e;
	Span spStart, spEnd;

	spStart = lex.eat(tLParen).span;

	while (lex.current() != tRParen)
	{
		e = parseExp(lex);
		exps.push_back(e);

		if (lex.current() == tComma)
			lex.advance();
		else
			break;
	}
	
	spEnd = lex.eat(tRParen).span;

	return Exp::make(eTuple, exps, spStart + spEnd);
}
Example #17
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;
	}
}
Example #18
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);
}
Example #19
0
ExpPtr parseTermPostfix (Lexer& lex, ExpPtr in)
{
	for (;;)
		switch (lex.current().tok)
		{
		case tLParen:
			in = parseCall(lex, in);
			break;

		case tDot:
			in = parseMem(lex, in);
			break;

		default:
			return in;
		}
}
Example #20
0
TypeDecl parseTypeDecl (Lexer& lex)
{
	Span spStart, spEnd, spType;
	std::vector<FuncDecl> ctors;

	spStart = lex.eat(tType).span;

	auto ty = parseType(lex, spType);

	if (ty->kind != tyConcrete)
		throw spType.die("invalid form of type in declaration");

	for (auto sub = ty->subtypes; !sub.nil(); ++sub)
	{
		auto sty = sub.head();

		if (sty->kind != tyPoly)
			throw spType.die("arguments to type must be polytypes");

		for (auto sty2 : sub.tail())
			if (sty2->kind == tyPoly &&
					sty->name == sty2->name)
				throw spType.die("identical polytypes in declaration");
	}

	lex.eat(tEqual);
	for (;;)
	{
		auto ctor = parseConstructor(lex);
		spEnd = ctor.span;
		ctors.push_back(ctor);

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

	return TypeDecl
		{
			ty->name,
			ty->subtypes,
			std::move(ctors),
			spStart + spEnd
		};
}
Example #21
0
ExpPtr parseiCall (Lexer& lex)
{
	// ^call <ty> <name>
	Span spStart, spEnd, spType;

	spStart = lex.eat(tiCall).span;
	auto ty = parseType(lex, spType);
	spEnd = lex.current().span;
	auto tag = lex.eat(tString).str;

	if (ty->kind != tyConcrete || ty->name != "Fn")
		throw spType.die("^call expects function type");

	auto e = Exp::make(eiCall, tag, {}, spStart + spEnd);
	e->setType(ty);

	return e;
}
Example #22
0
bool parseToplevel (Lexer& lex, GlobProto& proto)
{
	switch (lex.current().tok)
	{
	case tFunc:
		proto.funcs.push_back(parseFuncDecl(lex));
		return true;
	case tImport:
		proto.imports.push_back(parseImportDecl(lex));
		return true;
	case tType:
		proto.types.push_back(parseTypeDecl(lex));
		return true;
	case tPub:
		parsePublic(lex, proto);
		return true;
	default:
		return false;
	}
}
Example #23
0
ExpPtr parseLoop (Lexer& lex)
{
	Span spStart, spEnd;
	ExpPtr body;

	spStart = lex.eat(tLoop).span;

	ExpList sub;
	sub.reserve(2);
	if (lex.current() == tLCurl)
	{
		sub.push_back(body = parseBlock(lex));
	}
	else
	{
		sub.push_back(parseExp(lex));
		sub.push_back(body = parseBlock(lex));
	}
	spEnd = body->span;

	return Exp::make(eLoop, std::move(sub), spStart + spEnd);
}
Example #24
0
TyPtr parseTypeTuple (Lexer& lex, Span& sp)
{
	Span spStart, spEnd;

	std::vector<TyPtr> inners;
	parseTypeTupleRaw(lex, inners, spStart);

	if (lex.current() == tArrow)
	{
		lex.advance();
		inners.push_back(parseType(lex, spEnd));

		sp = spStart + spEnd;
		return Ty::makeFn(inners);
	}

	sp = spStart;

	if (inners.size() == 1)
		return inners[0];

	return Ty::makeConcrete("Tuple", inners);
}
Example #25
0
ExpPtr parseiPut (Lexer& lex)
{
	throw lex.current().span.die("^put unimplemented");
}