summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--ast/ast.cpp18
-rw-r--r--ast/ast.hpp29
-rw-r--r--parse/expr.cpp191
-rw-r--r--parse/lex.cpp47
-rw-r--r--parse/root.cpp27
5 files changed, 230 insertions, 82 deletions
diff --git a/ast/ast.cpp b/ast/ast.cpp
index a6eaa039..ffe485cb 100644
--- a/ast/ast.cpp
+++ b/ast/ast.cpp
@@ -79,6 +79,12 @@ ExprNode::ExprNode(TagBlock, ::std::vector<ExprNode> nodes)
ExprNode::ExprNode(TagLetBinding, Pattern pat, ExprNode value)
{
}
+ExprNode::ExprNode(TagReturn, ExprNode val)
+{
+}
+ExprNode::ExprNode(TagCast, ExprNode value, TypeRef dst_type)
+{
+}
ExprNode::ExprNode(TagInteger, uint64_t value, enum eCoreType datatype)
{
}
@@ -88,12 +94,24 @@ ExprNode::ExprNode(TagStructLiteral, Path path, ExprNode base_value, ::std::vect
ExprNode::ExprNode(TagCallPath, Path path, ::std::vector<ExprNode> args)
{
}
+ExprNode::ExprNode(TagCallObject, ExprNode val, ::std::vector<ExprNode> args)
+{
+}
ExprNode::ExprNode(TagMatch, ExprNode val, ::std::vector< ::std::pair<Pattern,ExprNode> > arms)
{
}
+ExprNode::ExprNode(TagIf, ExprNode cond, ExprNode true_code, ExprNode false_code)
+{
+}
ExprNode::ExprNode(TagNamedValue, Path path)
{
}
+ExprNode::ExprNode(TagField, ::std::string name)
+{
+}
+ExprNode::ExprNode(TagBinOp, BinOpType type, ExprNode left, ExprNode right)
+{
+}
TypeParam::TypeParam(bool is_lifetime, ::std::string name)
{
diff --git a/ast/ast.hpp b/ast/ast.hpp
index 2c8b06c0..f05747ac 100644
--- a/ast/ast.hpp
+++ b/ast/ast.hpp
@@ -72,9 +72,15 @@ public:
struct TagLetBinding {};
ExprNode(TagLetBinding, Pattern pat, ExprNode value);
+ struct TagReturn {};
+ ExprNode(TagReturn, ExprNode val);
+
struct TagAssign {};
ExprNode(TagAssign, ExprNode slot, ExprNode value) {}
+ struct TagCast {};
+ ExprNode(TagCast, ExprNode value, TypeRef dst_type);
+
struct TagInteger {};
ExprNode(TagInteger, uint64_t value, enum eCoreType datatype);
@@ -84,11 +90,34 @@ public:
struct TagCallPath {};
ExprNode(TagCallPath, Path path, ::std::vector<ExprNode> args);
+ struct TagCallObject {};
+ ExprNode(TagCallObject, ExprNode val, ::std::vector<ExprNode> args);
+
struct TagMatch {};
ExprNode(TagMatch, ExprNode val, ::std::vector< ::std::pair<Pattern,ExprNode> > arms);
+ struct TagIf {};
+ ExprNode(TagIf, ExprNode cond, ExprNode true_code, ExprNode false_code);
+
struct TagNamedValue {};
ExprNode(TagNamedValue, Path path);
+
+ struct TagField {};
+ ExprNode(TagField, ::std::string name);
+
+ enum BinOpType {
+ BINOP_CMPEQU,
+ BINOP_CMPNEQU,
+
+ BINOP_BITAND,
+ BINOP_BITOR,
+ BINOP_BITXOR,
+
+ BINOP_SHL,
+ BINOP_SHR,
+ };
+ struct TagBinOp {};
+ ExprNode(TagBinOp, BinOpType type, ExprNode left, ExprNode right);
};
class Expr
diff --git a/parse/expr.cpp b/parse/expr.cpp
index 22f774bb..29741b85 100644
--- a/parse/expr.cpp
+++ b/parse/expr.cpp
@@ -11,6 +11,7 @@
using AST::ExprNode;
AST::ExprNode Parse_ExprBlockNode(TokenStream& lex);
+AST::ExprNode Parse_Stmt(TokenStream& lex, bool& opt_semicolon);
AST::ExprNode Parse_Expr0(TokenStream& lex);
AST::ExprNode Parse_ExprBlocks(TokenStream& lex);
AST::ExprNode Parse_Expr1(TokenStream& lex);
@@ -27,6 +28,8 @@ AST::Expr Parse_ExprBlock(TokenStream& lex)
AST::Pattern Parse_Pattern(TokenStream& lex)
{
+ TRACE_FUNCTION;
+
AST::Path path;
Token tok;
tok = lex.getToken();
@@ -89,67 +92,77 @@ AST::Pattern Parse_Pattern(TokenStream& lex)
ExprNode Parse_ExprBlockNode(TokenStream& lex)
{
+ TRACE_FUNCTION;
+
::std::vector<ExprNode> nodes;
Token tok;
- bool trailing_value = false;
GET_CHECK_TOK(tok, lex, TOK_BRACE_OPEN);
- while( (tok = lex.getToken()).type() != TOK_BRACE_CLOSE )
+ while( GET_TOK(tok, lex) != TOK_BRACE_CLOSE )
{
- // 1. Handle 'let'
- // 2. Handle new blocks
- // 3. Handle a sequence of expressions broken by ';'
- switch(tok.type())
- {
- case TOK_BRACE_OPEN:
- lex.putback(tok);
- nodes.push_back(Parse_ExprBlockNode(lex));
- trailing_value = true;
- break;
- case TOK_RWORD_LET: {
- //ret.append();
- AST::Pattern pat = Parse_Pattern(lex);
- GET_CHECK_TOK(tok, lex, TOK_EQUAL);
- AST::ExprNode val = Parse_Expr1(lex);
- GET_CHECK_TOK(tok, lex, TOK_SEMICOLON);
- trailing_value = false;
- nodes.push_back( ExprNode(ExprNode::TagLetBinding(), pat, val));
- break; }
- case TOK_RWORD_LOOP:
- throw ParseError::Todo("loop");
- break;
- case TOK_RWORD_FOR:
- throw ParseError::Todo("for");
- break;
- case TOK_RWORD_WHILE:
- throw ParseError::Todo("while");
- break;
- default:
- lex.putback(tok);
- nodes.push_back(Parse_Expr0(lex));
- tok = lex.getToken();
- if(tok.type() != TOK_SEMICOLON)
- {
- if(tok.type() != TOK_BRACE_CLOSE)
- throw ParseError::Unexpected(tok, Token(TOK_SEMICOLON));
- else
- lex.putback(tok);
- trailing_value = true;
- }
- else{
- trailing_value = false;
- }
+ lex.putback(tok);
+ bool opt_semicolon = false;
+ // NOTE: This semicolon handling is SHIT.
+ nodes.push_back(Parse_Stmt(lex, opt_semicolon));
+ if( GET_TOK(tok, lex) != TOK_BRACE_CLOSE ) {
+ if( !opt_semicolon )
+ CHECK_TOK(tok, TOK_SEMICOLON);
+ else
+ lex.putback(tok);
+ }
+ else {
+ nodes.push_back(ExprNode());
break;
}
}
- if( trailing_value == false )
+ return AST::ExprNode(ExprNode::TagBlock(), nodes);
+}
+
+AST::ExprNode Parse_Stmt(TokenStream& lex, bool& opt_semicolon)
+{
+ TRACE_FUNCTION;
+
+ Token tok;
+ // 1. Handle 'let'
+ // 2. Handle new blocks
+ // 3. Handle a sequence of expressions broken by ';'
+ switch(GET_TOK(tok, lex))
{
- nodes.push_back(ExprNode());
+ case TOK_BRACE_OPEN:
+ lex.putback(tok);
+ opt_semicolon = true;
+ return Parse_ExprBlockNode(lex);
+ case TOK_RWORD_LET: {
+ //ret.append();
+ AST::Pattern pat = Parse_Pattern(lex);
+ GET_CHECK_TOK(tok, lex, TOK_EQUAL);
+ AST::ExprNode val = Parse_Expr1(lex);
+ opt_semicolon = false;
+ return ExprNode(ExprNode::TagLetBinding(), pat, val);
+ }
+ case TOK_RWORD_RETURN:
+ return ExprNode(ExprNode::TagReturn(), Parse_Expr1(lex));
+ case TOK_RWORD_LOOP:
+ throw ParseError::Todo("loop");
+ break;
+ case TOK_RWORD_FOR:
+ throw ParseError::Todo("for");
+ break;
+ case TOK_RWORD_WHILE:
+ throw ParseError::Todo("while");
+ break;
+ default: {
+ lex.putback(tok);
+ opt_semicolon = true;
+ return Parse_Expr0(lex);
+ }
}
- return AST::ExprNode(ExprNode::TagBlock(), nodes);
+
}
::std::vector<AST::ExprNode> Parse_ParenList(TokenStream& lex)
{
+ TRACE_FUNCTION;
+
::std::vector<ExprNode> rv;
Token tok;
GET_CHECK_TOK(tok, lex, TOK_PAREN_OPEN);
@@ -167,6 +180,8 @@ ExprNode Parse_ExprBlockNode(TokenStream& lex)
// 0: Assign
AST::ExprNode Parse_Expr0(TokenStream& lex)
{
+ TRACE_FUNCTION;
+
AST::ExprNode rv = Parse_ExprBlocks(lex);
Token tok = lex.getToken();
if( tok.type() == TOK_EQUAL )
@@ -181,6 +196,41 @@ AST::ExprNode Parse_Expr0(TokenStream& lex)
return rv;
}
+AST::ExprNode Parse_IfStmt(TokenStream& lex)
+{
+ TRACE_FUNCTION;
+
+ Token tok;
+ ExprNode cond;
+ if( GET_TOK(tok, lex) == TOK_RWORD_LET ) {
+ throw ParseError::Todo("if let");
+ }
+ else {
+ lex.putback(tok);
+ cond = Parse_Expr0(lex);
+ }
+
+ ExprNode code = Parse_ExprBlockNode(lex);
+
+ ExprNode altcode;
+ if( GET_TOK(tok, lex) == TOK_RWORD_ELSE )
+ {
+ if( GET_TOK(tok, lex) == TOK_RWORD_IF ) {
+ altcode = Parse_IfStmt(lex);
+ }
+ else {
+ lex.putback(tok);
+ altcode = Parse_ExprBlockNode(lex);
+ }
+ }
+ else {
+ lex.putback(tok);
+ altcode = ExprNode();
+ }
+
+ return ExprNode(ExprNode::TagIf(), cond, code, altcode);
+}
+
// 0.5: Blocks
AST::ExprNode Parse_ExprBlocks(TokenStream& lex)
{
@@ -198,15 +248,16 @@ AST::ExprNode Parse_ExprBlocks(TokenStream& lex)
lex.putback(tok);
AST::Pattern pat = Parse_Pattern(lex);
GET_CHECK_TOK(tok, lex, TOK_FATARROW);
- AST::ExprNode val = Parse_Expr0(lex);
+ bool opt_semicolon = false;
+ AST::ExprNode val = Parse_Stmt(lex, opt_semicolon);
arms.push_back( ::std::make_pair(pat, val) );
} while( GET_TOK(tok, lex) == TOK_COMMA );
CHECK_TOK(tok, TOK_BRACE_CLOSE);
return AST::ExprNode(ExprNode::TagMatch(), switch_val, arms);
}
case TOK_RWORD_IF:
- throw ParseError::Todo("if");
- break;
+ // TODO: if let
+ return Parse_IfStmt(lex);
default:
lex.putback(tok);
return Parse_Expr1(lex);
@@ -214,11 +265,12 @@ AST::ExprNode Parse_ExprBlocks(TokenStream& lex)
}
-#define LEFTASSOC(cur, next, cases) \
-AST::ExprNode next(TokenStream& lex); \
+#define LEFTASSOC(cur, _next, cases) \
+AST::ExprNode _next(TokenStream& lex); \
AST::ExprNode cur(TokenStream& lex) \
{ \
::std::cout << ">>" << #cur << ::std::endl; \
+ AST::ExprNode (*next)(TokenStream&) = _next;\
AST::ExprNode rv = next(lex); \
while(true) \
{ \
@@ -246,9 +298,11 @@ LEFTASSOC(Parse_Expr2, Parse_Expr3,
// 3: (In)Equality
LEFTASSOC(Parse_Expr3, Parse_Expr4,
case TOK_DOUBLE_EQUAL:
- throw ParseError::Todo("expr - equal");
+ rv = ExprNode(ExprNode::TagBinOp(), ExprNode::BINOP_CMPEQU, rv, next(lex));
+ break;
case TOK_EXCLAM_EQUAL:
- throw ParseError::Todo("expr - not equal");
+ rv = ExprNode(ExprNode::TagBinOp(), ExprNode::BINOP_CMPNEQU, rv, next(lex));
+ break;
)
// 4: Comparisons
LEFTASSOC(Parse_Expr4, Parse_Expr5,
@@ -264,24 +318,29 @@ LEFTASSOC(Parse_Expr4, Parse_Expr5,
// 5: Bit OR
LEFTASSOC(Parse_Expr5, Parse_Expr6,
case TOK_PIPE:
- throw ParseError::Todo("expr - bitwise OR");
+ rv = ExprNode(ExprNode::TagBinOp(), ExprNode::BINOP_BITOR, rv, next(lex));
+ break;
)
// 6: Bit XOR
LEFTASSOC(Parse_Expr6, Parse_Expr7,
case TOK_CARET:
- throw ParseError::Todo("expr - bitwise XOR");
+ rv = ExprNode(ExprNode::TagBinOp(), ExprNode::BINOP_BITXOR, rv, next(lex));
+ break;
)
// 7: Bit AND
LEFTASSOC(Parse_Expr7, Parse_Expr8,
case TOK_AMP:
- throw ParseError::Todo("expr - bitwise AND");
+ rv = ExprNode(ExprNode::TagBinOp(), ExprNode::BINOP_BITAND, rv, next(lex));
+ break;
)
// 8: Bit Shifts
LEFTASSOC(Parse_Expr8, Parse_Expr9,
case TOK_DOUBLE_LT:
- throw ParseError::Todo("expr - shift left");
+ rv = ExprNode(ExprNode::TagBinOp(), ExprNode::BINOP_SHL, rv, next(lex));
+ break;
case TOK_DOUBLE_GT:
- throw ParseError::Todo("expr - shift right");
+ rv = ExprNode(ExprNode::TagBinOp(), ExprNode::BINOP_SHR, rv, next(lex));
+ break;
)
// 9: Add / Subtract
LEFTASSOC(Parse_Expr9, Parse_Expr10,
@@ -293,7 +352,8 @@ LEFTASSOC(Parse_Expr9, Parse_Expr10,
// 10: Cast
LEFTASSOC(Parse_Expr10, Parse_Expr11,
case TOK_RWORD_AS:
- throw ParseError::Todo("expr - cast");
+ rv = ExprNode(ExprNode::TagCast(), rv, Parse_Type(lex));
+ break;
)
// 11: Times / Divide / Modulo
LEFTASSOC(Parse_Expr11, Parse_Expr12,
@@ -338,11 +398,14 @@ AST::ExprNode Parse_ExprFC(TokenStream& lex)
{
case TOK_PAREN_OPEN:
// Function call
- throw ParseError::Todo("Function call / structure literal");
+ lex.putback(tok);
+ val = AST::ExprNode(AST::ExprNode::TagCallObject(), val, Parse_ParenList(lex));
break;
case TOK_DOT:
// Field access
- throw ParseError::Todo("Field access");
+ // TODO: What about tuple indexing?
+ GET_CHECK_TOK(tok, lex, TOK_IDENT);
+ val = AST::ExprNode(AST::ExprNode::TagField(), tok.str());
break;
default:
lex.putback(tok);
@@ -411,6 +474,8 @@ AST::ExprNode Parse_ExprVal(TokenStream& lex)
path.append( AST::PathNode("self", ::std::vector<TypeRef>()) );
return ExprNode(ExprNode::TagNamedValue(), path);
}
+ case TOK_PAREN_OPEN:
+ return Parse_Expr0(lex);
case TOK_MACRO: {
// Need to create a token tree, pass to the macro, then pass the result of that to Parse_Expr0
MacroExpander expanded_macro = Macro_Invoke(tok.str().c_str(), Parse_TT(lex));
diff --git a/parse/lex.cpp b/parse/lex.cpp
index 4c1103a1..e80f42ca 100644
--- a/parse/lex.cpp
+++ b/parse/lex.cpp
@@ -218,7 +218,47 @@ Token Lexer::getToken()
{
// No match at all, check for symbol
char ch = this->getc();
- if( issym(ch) )
+ if( isdigit(ch) )
+ {
+ // TODO: handle integers/floats
+ uint64_t val = 0;
+ if( ch == '0' ) {
+ // Octal/hex handling
+ ch = this->getc();
+ if( ch == 'x' ) {
+ while( isxdigit(ch = this->getc()) ) {
+ val *= val * 16;
+ if(ch <= '9')
+ val += ch - '0';
+ else if( ch <= 'F' )
+ val += ch - 'A' + 10;
+ else if( ch <= 'f' )
+ val += ch - 'a' + 10;
+ }
+ }
+ else if( isdigit(ch) ) {
+ throw ParseError::Todo("Lex octal numbers");
+ }
+ else {
+ val = 0;
+ }
+ }
+ else {
+ throw ParseError::Todo("Lex decimal numbers");
+ }
+
+ if(ch == 'u' || ch == 'i') {
+ // Unsigned
+ throw ParseError::Todo("Lex number suffixes");
+ }
+ else if( ch == '.' ) {
+ throw ParseError::Todo("Lex floats");
+ }
+ else {
+ return Token(val, CORETYPE_ANY);
+ }
+ }
+ else if( issym(ch) )
{
::std::string str;
while( issym(ch) )
@@ -242,11 +282,6 @@ Token Lexer::getToken()
return Token(TOK_IDENT, str);
}
}
- else if( isdigit(ch) )
- {
- // TODO: handle integers/floats
- throw ParseError::Todo("Lex Numbers");
- }
else
{
throw ParseError::BadChar(ch);
diff --git a/parse/root.cpp b/parse/root.cpp
index 2dac321a..f123eee6 100644
--- a/parse/root.cpp
+++ b/parse/root.cpp
@@ -76,18 +76,18 @@ static const struct {
enum eCoreType type;
} CORETYPES[] = {
{"char", CORETYPE_CHAR},
- {"uint", CORETYPE_UINT},
- {"int", CORETYPE_INT},
- {"u8", CORETYPE_U8},
+ {"f32", CORETYPE_F32},
+ {"f64", CORETYPE_F64},
+ {"i16", CORETYPE_I16},
+ {"i32", CORETYPE_I32},
+ {"i64", CORETYPE_I64},
{"i8", CORETYPE_I8},
+ {"int", CORETYPE_INT},
{"u16", CORETYPE_U16},
- {"i16", CORETYPE_I16},
{"u32", CORETYPE_U32},
- {"i32", CORETYPE_I32},
{"u64", CORETYPE_U64},
- {"i64", CORETYPE_I64},
- {"f32", CORETYPE_F32},
- {"f64", CORETYPE_F64}
+ {"u8", CORETYPE_U8},
+ {"uint", CORETYPE_UINT},
};
TypeRef Parse_Type(TokenStream& lex)
@@ -126,11 +126,10 @@ TypeRef Parse_Type(TokenStream& lex)
// Immutable reference
return TypeRef(TypeRef::TagReference(), false, Parse_Type(lex));
}
- break;
+ throw ParseError::BugCheck("Reached end of Parse_Type:AMP");
case TOK_STAR:
// Pointer
- tok = lex.getToken();
- switch( tok.type() )
+ switch( GET_TOK(tok, lex) )
{
case TOK_RWORD_MUT:
// Mutable pointer
@@ -141,7 +140,7 @@ TypeRef Parse_Type(TokenStream& lex)
default:
throw ParseError::Unexpected(tok, Token(TOK_RWORD_CONST));
}
- break;
+ throw ParseError::BugCheck("Reached end of Parse_Type:STAR");
case TOK_SQUARE_OPEN: {
// Array
TypeRef inner = Parse_Type(lex);
@@ -157,7 +156,8 @@ TypeRef Parse_Type(TokenStream& lex)
GET_CHECK_TOK(tok, lex, TOK_SQUARE_CLOSE);
return TypeRef(TypeRef::TagUnsizedArray(), inner);
}
- break; }
+ throw ParseError::BugCheck("Reached end of Parse_Type:SQUARE");
+ }
case TOK_PAREN_OPEN: {
::std::vector<TypeRef> types;
if( (tok = lex.getToken()).type() == TOK_PAREN_CLOSE)
@@ -174,6 +174,7 @@ TypeRef Parse_Type(TokenStream& lex)
default:
throw ParseError::Unexpected(tok);
}
+ throw ParseError::BugCheck("Reached end of Parse_Type");
}
AST::TypeParams Parse_TypeParams(TokenStream& lex)