Permalink
Browse files

implemented advanced local type inference

  • Loading branch information...
1 parent 300378e commit 7cc57a43513ec694869b851321d8be34936e203c @peryaudo committed with peryaudo Sep 3, 2013
View
@@ -73,7 +73,6 @@ Peryanではオブジェクト指向など多くの機能が未だ実装され
今後実装される予定の物には以下のものがあります。
また、詳細なドキュメントも今後用意される予定です。
-* 本格的な型推論器
* オブジェクト指向
* variant型
* パターンマッチ
@@ -97,5 +96,8 @@ Peryanの処理系はMITライセンスの下に提供されます。詳しく
## 参考文献
* 柏木 餅子, 風薬 『きつねさんでもわかるLLVM 〜コンパイラを自作するためのガイドブック〜』 2013年
-* (著) Terence Parr, (監訳) 中田 育男, (訳) 伊藤 真浩 『言語実装パターン』 2011年
+* Terence Parr 『言語実装パターン』 2011年
+* Benjamin C. Pierce 『型システム入門 -プログラミング言語と型の理論-』2013年
+* Benjamin C. Pierce, David N. Turner "Local Type Inference" ACM TOPLAS Vol. 22 No.1 Jan. 2000
+
View
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
View
@@ -45,7 +45,7 @@ void Parser::parse() throw (LexerError, ParserError, SemanticsError) {
if (options_.verbose) std::cerr<<"ok."<<std::endl;
if (options_.verbose) std::cerr<<"resolving types...";
- TypeResolver typeResolver(getSymbolTable());
+ TypeResolver typeResolver(getSymbolTable(), options_);
typeResolver.visit(getTransUnit());
if (options_.verbose) {
std::cerr<<"ok."<<std::endl;
@@ -222,23 +222,25 @@ FuncDefStmt *Parser::parseFuncDefStmt() throw (LexerError, ParserError) {
Identifier *curParam = parseIdentifier();
- // TODO: will be optional
- if (la() != Token::CLNCLN)
- throw ParserError(getPosition(), "error: STUB: type inference not implemented yet");
- consume();
+ if (la() == Token::CLNCLN) {
+ consume();
- curParam->typeSpec = parseTypeSpec();
+ curParam->typeSpec = parseTypeSpec();
+ }
params.push_back(curParam);
}
consume();
- if (la() != Token::CLNCLN)
- throw ParserError(getPosition(), "error: '::' expected");
- consume();
+ TypeSpec *retTypeSpec = NULL;
+ if (la() == Token::CLNCLN) {
+ consume();
- TypeSpec *retType = parseTypeSpec();
+ retTypeSpec = parseTypeSpec();
+ } else {
+ retTypeSpec = NULL;
+ }
if (la() != Token::LBRACE)
throw ParserError(getPosition(), "error: '{' expected");
@@ -252,7 +254,7 @@ FuncDefStmt *Parser::parseFuncDefStmt() throw (LexerError, ParserError) {
FuncDefStmt *fds = new FuncDefStmt(token, name, body);
fds->params = params;
- fds->retTypeSpec = retType;
+ fds->retTypeSpec = retTypeSpec;
DBG_PRINT(-, parseFuncDefStmt);
return fds;
@@ -1116,23 +1118,25 @@ Expr *Parser::parseFuncExpr() throw (LexerError, ParserError) {
Identifier *curParam = parseIdentifier();
- // TODO: will be optional
- if (la() != Token::CLNCLN)
- throw ParserError(getPosition(), "error: STUB: type inference not implemented yet");
- consume();
+ if (la() == Token::CLNCLN) {
+ consume();
- curParam->typeSpec = parseTypeSpec();
+ curParam->typeSpec = parseTypeSpec();
+ } else {
+ curParam->typeSpec = NULL;
+ }
params.push_back(curParam);
}
consume();
- if (la() != Token::CLNCLN)
- throw ParserError(getPosition(), "error: '::' expected");
- consume();
+ TypeSpec *retTypeSpec = NULL;
+ if (la() == Token::CLNCLN) {
+ consume();
- TypeSpec *retType = parseTypeSpec();
+ retTypeSpec = parseTypeSpec();
+ }
if (la() != Token::LBRACE)
throw ParserError(getPosition(), "error: '{' expected");
@@ -1141,7 +1145,7 @@ Expr *Parser::parseFuncExpr() throw (LexerError, ParserError) {
FuncExpr *fe = new FuncExpr(token, body);
fe->params = params;
- fe->retTypeSpec = retType;
+ fe->retTypeSpec = retTypeSpec;
return fe;
}
View
@@ -58,11 +58,13 @@ void SymbolResolver::visit(FuncDefStmt *fds, Scope *scope) throw (SemanticsError
scope = fds->symbol;
- visit(fds->retTypeSpec, scope);
+ if (fds->retTypeSpec != NULL) {
+ visit(fds->retTypeSpec, scope);
+ }
- Type *curType = fds->retTypeSpec->type;
+ Type *curType = (fds->retTypeSpec != NULL ? fds->retTypeSpec->type : NULL);
- if (curType->getTypeType() == Type::NAMESPACE_TYPE) {
+ if (curType != NULL && curType->getTypeType() == Type::NAMESPACE_TYPE) {
throw SemanticsError(fds->token.getPosition(),
std::string("error : cannot use namespace type ")
+ curType->getTypeName()
@@ -73,9 +75,8 @@ void SymbolResolver::visit(FuncDefStmt *fds, Scope *scope) throw (SemanticsError
for (std::vector<Identifier *>::reverse_iterator it = fds->params.rbegin();
it != fds->params.rend(); ++it) {
visit(*it, scope);
- assert((*it)->type != NULL);
- if ((*it)->type->getTypeType() == Type::NAMESPACE_TYPE) {
+ if ((*it)->type != NULL && (*it)->type->getTypeType() == Type::NAMESPACE_TYPE) {
throw SemanticsError(fds->token.getPosition(),
std::string("error : cannot use namespace type ")
+ (*it)->type->getTypeName()
@@ -352,36 +353,36 @@ void SymbolResolver::visit(UnaryExpr *ue, Scope *scope) throw (SemanticsError) {
void SymbolResolver::visit(IntLiteralExpr *lit, Scope *scope) throw (SemanticsError) {
DBG_PRINT(+, IntLiteralExpr);
assert(lit != NULL);
- lit->type = static_cast<BuiltInTypeSymbol *>(scope->resolve("Int"));
+ //lit->type = static_cast<BuiltInTypeSymbol *>(scope->resolve("Int"));
DBG_PRINT(-, IntLiteralExpr);
return;
}
void SymbolResolver::visit(StrLiteralExpr *lit, Scope *scope) throw (SemanticsError) {
DBG_PRINT(+-, StrLiteralExpr);
assert(lit != NULL);
- lit->type = static_cast<BuiltInTypeSymbol *>(scope->resolve("String"));
+ //lit->type = static_cast<BuiltInTypeSymbol *>(scope->resolve("String"));
return;
}
void SymbolResolver::visit(CharLiteralExpr *lit, Scope *scope) throw (SemanticsError) {
DBG_PRINT(+-, CharLiteralExpr);
assert(lit != NULL);
- lit->type = static_cast<BuiltInTypeSymbol *>(scope->resolve("Char"));
+ //lit->type = static_cast<BuiltInTypeSymbol *>(scope->resolve("Char"));
return;
}
void SymbolResolver::visit(FloatLiteralExpr *lit, Scope *scope) throw (SemanticsError) {
DBG_PRINT(+-, FloatLiteralExpr);
assert(lit != NULL);
- lit->type = static_cast<BuiltInTypeSymbol *>(scope->resolve("Float"));
+ //lit->type = static_cast<BuiltInTypeSymbol *>(scope->resolve("Double"));
return;
}
void SymbolResolver::visit(BoolLiteralExpr *lit, Scope *scope) throw (SemanticsError) {
DBG_PRINT(+-, BoolLiteralExpr);
assert(lit != NULL);
- lit->type = static_cast<BuiltInTypeSymbol *>(scope->resolve("Bool"));
+ //lit->type = static_cast<BuiltInTypeSymbol *>(scope->resolve("Bool"));
return;
}
View
@@ -46,6 +46,7 @@ class Type {
virtual TypeType getTypeType() { return TYPE; }
Type(const std::string& name) : name_(name) {}
+
virtual std::string getTypeName() { return name_; }
virtual bool is(Type *to) {
@@ -121,12 +122,14 @@ class FuncType : public Type {
FuncType(Type *car, Type *cdr) : Type("->"), car_(car), cdr_(cdr) {}
virtual std::string getTypeName() {
- return car_->getTypeName() + std::string(" -> ") + cdr_->getTypeName();
+ return (car_ != NULL ? car_->getTypeName() : std::string("NULL"))
+ + std::string(" -> ")
+ + (cdr_ != NULL ? cdr_->getTypeName() : std::string("NULL"));
}
virtual TypeType getTypeType() { return FUNC_TYPE; }
- Type *getCar() { return car_; }
- Type *getCdr() { return cdr_; }
+ Type *& getCar() { return car_; }
+ Type *& getCdr() { return cdr_; }
virtual bool is(Type *to) {
if (to->getTypeType() != FUNC_TYPE)
@@ -136,13 +139,12 @@ class FuncType : public Type {
cdr_->is(static_cast<FuncType *>(to)->getCdr());
}
- Type *getReturnType() {
- Type *ret = this;
- while (ret->getTypeType() == FUNC_TYPE) {
- ret = static_cast<FuncType *>(ret)->getCdr();
- assert(ret != NULL);
- }
- return ret;
+ Type *& getReturnType() {
+ if (this->cdr_ == NULL)
+ return this->cdr_;
+ if (this->cdr_->getTypeType() != Type::FUNC_TYPE)
+ return this->cdr_;
+ return static_cast<FuncType *>(this->cdr_)->getReturnType();
}
};
Oops, something went wrong.

0 comments on commit 7cc57a4

Please sign in to comment.