diff options
-rw-r--r-- | ast/ast.cpp | 13 | ||||
-rw-r--r-- | ast/ast.hpp | 11 | ||||
-rw-r--r-- | mrustc.cbp | 16 | ||||
-rw-r--r-- | mrustc.depend | 10 | ||||
-rw-r--r-- | mrustc.layout | 74 | ||||
-rw-r--r-- | parse/common.hpp | 5 | ||||
-rw-r--r-- | parse/expr.cpp | 268 | ||||
-rw-r--r-- | parse/root.cpp | 91 |
8 files changed, 474 insertions, 14 deletions
diff --git a/ast/ast.cpp b/ast/ast.cpp index 5c9c566e..4bba2b61 100644 --- a/ast/ast.cpp +++ b/ast/ast.cpp @@ -15,7 +15,20 @@ void Module::add_global(bool is_public, bool is_mut, ::std::string name, TypeRef {
::std::cout << "add_global()" << ::std::endl;
}
+void Module::add_struct(bool is_public, ::std::string name, TypeParams params, ::std::vector<StructItem> items)
+{
+}
+void Module::add_function(bool is_public, ::std::string name, TypeParams params, TypeRef ret_type, ::std::vector<StructItem> args, Expr code)
+{
+}
+ExprNode::ExprNode()
+{
+
+}
+ExprNode::ExprNode(TagBlock, ::std::vector<ExprNode> nodes)
+{
+}
ExprNode::ExprNode(TagInteger, uint64_t value, enum eCoreType datatype)
{
diff --git a/ast/ast.hpp b/ast/ast.hpp index f84f322f..c3bc549b 100644 --- a/ast/ast.hpp +++ b/ast/ast.hpp @@ -18,16 +18,22 @@ public: class ExprNode
{
public:
+ ExprNode();
+
+ struct TagBlock {};
+ ExprNode(TagBlock, ::std::vector<ExprNode> nodes);
+
struct TagAssign {};
ExprNode(TagAssign, ExprNode slot, ExprNode value) {}
- struct TagInteger {};
+ struct TagInteger {};
ExprNode(TagInteger, uint64_t value, enum eCoreType datatype);
};
class Expr
{
public:
+ Expr() {}
Expr(ExprNode node) {}
};
@@ -40,6 +46,7 @@ public: };
typedef ::std::vector<TypeParam> TypeParams;
+typedef ::std::pair< ::std::string, TypeRef> StructItem;
class Module
{
@@ -47,6 +54,8 @@ public: void add_alias(bool is_public, Path path) {}
void add_constant(bool is_public, ::std::string name, TypeRef type, Expr val);
void add_global(bool is_public, bool is_mut, ::std::string name, TypeRef type, Expr val);
+ void add_struct(bool is_public, ::std::string name, TypeParams params, ::std::vector<StructItem> items);
+ void add_function(bool is_public, ::std::string name, TypeParams params, TypeRef ret_type, ::std::vector<StructItem> args, Expr code);
};
}
@@ -13,6 +13,7 @@ <Option compiler="gcc" /> <Compiler> <Add option="-g" /> + <Add directory="parse" /> </Compiler> </Target> <Target title="Release"> @@ -22,6 +23,7 @@ <Option compiler="gcc" /> <Compiler> <Add option="-O2" /> + <Add directory="parse" /> </Compiler> <Linker> <Add option="-s" /> @@ -32,7 +34,21 @@ <Add option="-Wall" /> <Add option="-fexceptions" /> </Compiler> + <Unit filename="ast/ast.cpp" /> + <Unit filename="ast/ast.hpp" /> + <Unit filename="coretypes.hpp" /> <Unit filename="main.cpp" /> + <Unit filename="parse/common.hpp" /> + <Unit filename="parse/expr.cpp" /> + <Unit filename="parse/lex.cpp" /> + <Unit filename="parse/lex.hpp" /> + <Unit filename="parse/parseerror.cpp" /> + <Unit filename="parse/parseerror.hpp" /> + <Unit filename="parse/preproc.cpp" /> + <Unit filename="parse/preproc.hpp" /> + <Unit filename="parse/root.cpp" /> + <Unit filename="samples/1.rs" /> + <Unit filename="types.hpp" /> <Extensions> <code_completion /> <envvars /> diff --git a/mrustc.depend b/mrustc.depend index 591bf552..ccbffbe4 100644 --- a/mrustc.depend +++ b/mrustc.depend @@ -35,26 +35,26 @@ 1416668029 c:\users\new\documents\code\mrustc\parse\preproc.hpp
"lex.hpp"
-1416748458 source:c:\users\new\documents\code\mrustc\parse\root.cpp
+1416750329 source:c:\users\new\documents\code\mrustc\parse\root.cpp
"preproc.hpp"
"../ast/ast.hpp"
"parseerror.hpp"
"common.hpp"
<cassert>
-1416748030 c:\users\new\documents\code\mrustc\ast\ast.hpp
+1416821767 c:\users\new\documents\code\mrustc\ast\ast.hpp
<string>
<vector>
"../coretypes.hpp"
-1416748091 source:c:\users\new\documents\code\mrustc\ast\ast.cpp
+1416821792 source:c:\users\new\documents\code\mrustc\ast\ast.cpp
"ast.hpp"
"../types.hpp"
<iostream>
-1416731433 c:\users\new\documents\code\mrustc\parse\common.hpp
+1416750065 c:\users\new\documents\code\mrustc\parse\common.hpp
-1416739817 source:c:\users\new\documents\code\mrustc\parse\expr.cpp
+1416821758 source:c:\users\new\documents\code\mrustc\parse\expr.cpp
"preproc.hpp"
"parseerror.hpp"
"../ast/ast.hpp"
diff --git a/mrustc.layout b/mrustc.layout new file mode 100644 index 00000000..080eab3c --- /dev/null +++ b/mrustc.layout @@ -0,0 +1,74 @@ +<?xml version="1.0" encoding="UTF-8" standalone="yes" ?> +<CodeBlocks_layout_file> + <ActiveTarget name="Debug" /> + <File name="parse\lex.hpp" open="1" top="0" tabpos="2" split="0" active="1" splitpos="0" zoom_1="0" zoom_2="0"> + <Cursor> + <Cursor1 position="3076" topLine="129" /> + </Cursor> + </File> + <File name="parse\parseerror.hpp" open="0" top="0" tabpos="0" split="0" active="1" splitpos="0" zoom_1="0" zoom_2="0"> + <Cursor> + <Cursor1 position="660" topLine="12" /> + </Cursor> + </File> + <File name="types.hpp" open="1" top="0" tabpos="7" split="0" active="1" splitpos="0" zoom_1="0" zoom_2="0"> + <Cursor> + <Cursor1 position="758" topLine="0" /> + </Cursor> + </File> + <File name="ast\ast.cpp" open="1" top="0" tabpos="9" split="0" active="1" splitpos="0" zoom_1="0" zoom_2="0"> + <Cursor> + <Cursor1 position="915" topLine="4" /> + </Cursor> + </File> + <File name="parse\preproc.cpp" open="0" top="0" tabpos="0" split="0" active="1" splitpos="0" zoom_1="0" zoom_2="0"> + <Cursor> + <Cursor1 position="128" topLine="0" /> + </Cursor> + </File> + <File name="parse\expr.cpp" open="1" top="1" tabpos="5" split="0" active="1" splitpos="0" zoom_1="0" zoom_2="0"> + <Cursor> + <Cursor1 position="1916" topLine="56" /> + </Cursor> + </File> + <File name="parse\lex.cpp" open="0" top="0" tabpos="0" split="0" active="1" splitpos="0" zoom_1="0" zoom_2="0"> + <Cursor> + <Cursor1 position="15276" topLine="469" /> + </Cursor> + </File> + <File name="parse\parseerror.cpp" open="0" top="0" tabpos="0" split="0" active="1" splitpos="0" zoom_1="0" zoom_2="0"> + <Cursor> + <Cursor1 position="726" topLine="0" /> + </Cursor> + </File> + <File name="ast\ast.hpp" open="1" top="0" tabpos="8" split="0" active="1" splitpos="0" zoom_1="0" zoom_2="0"> + <Cursor> + <Cursor1 position="299" topLine="12" /> + </Cursor> + </File> + <File name="samples\1.rs" open="1" top="0" tabpos="3" split="0" active="1" splitpos="0" zoom_1="0" zoom_2="0"> + <Cursor> + <Cursor1 position="217" topLine="15" /> + </Cursor> + </File> + <File name="parse\common.hpp" open="1" top="0" tabpos="6" split="0" active="1" splitpos="0" zoom_1="0" zoom_2="0"> + <Cursor> + <Cursor1 position="571" topLine="0" /> + </Cursor> + </File> + <File name="parse\root.cpp" open="1" top="0" tabpos="4" split="0" active="1" splitpos="0" zoom_1="0" zoom_2="0"> + <Cursor> + <Cursor1 position="8738" topLine="254" /> + </Cursor> + </File> + <File name="parse\preproc.hpp" open="0" top="0" tabpos="0" split="0" active="1" splitpos="0" zoom_1="0" zoom_2="0"> + <Cursor> + <Cursor1 position="127" topLine="0" /> + </Cursor> + </File> + <File name="main.cpp" open="1" top="0" tabpos="1" split="0" active="1" splitpos="0" zoom_1="0" zoom_2="0"> + <Cursor> + <Cursor1 position="194" topLine="0" /> + </Cursor> + </File> +</CodeBlocks_layout_file> diff --git a/parse/common.hpp b/parse/common.hpp index 357944c4..34ea65a4 100644 --- a/parse/common.hpp +++ b/parse/common.hpp @@ -5,9 +5,14 @@ if((tok = lex.getToken()).type() != exp) \
throw ParseError::Unexpected(tok, Token(exp));\
} while(0)
+#define CHECK_TOK(tok, exp) do {\
+ if(tok.type() != exp) \
+ throw ParseError::Unexpected(tok, Token(exp));\
+} while(0)
extern AST::Path Parse_Path(TokenStream& lex, bool is_abs, bool generic_ok);
extern TypeRef Parse_Type(TokenStream& lex);
extern AST::Expr Parse_Expr(TokenStream& lex, bool const_only);
+extern AST::Expr Parse_ExprBlock(TokenStream& lex);
#endif // PARSE_COMMON_HPP_INCLUDED
diff --git a/parse/expr.cpp b/parse/expr.cpp new file mode 100644 index 00000000..997b49f5 --- /dev/null +++ b/parse/expr.cpp @@ -0,0 +1,268 @@ +/*
+ */
+#include "preproc.hpp"
+#include "parseerror.hpp"
+#include "../ast/ast.hpp"
+#include "common.hpp"
+#include <iostream>
+
+using AST::ExprNode;
+
+AST::ExprNode Parse_ExprBlockNode(TokenStream& lex);
+AST::ExprNode Parse_Expr0(TokenStream& lex);
+AST::ExprNode Parse_ExprBlocks(TokenStream& lex);
+AST::ExprNode Parse_Expr1(TokenStream& lex);
+
+AST::Expr Parse_Expr(TokenStream& lex, bool const_only)
+{
+ return AST::Expr(Parse_Expr0(lex));
+}
+
+AST::Expr Parse_ExprBlock(TokenStream& lex)
+{
+ return AST::Expr(Parse_ExprBlockNode(lex));
+}
+
+ExprNode Parse_ExprBlockNode(TokenStream& lex)
+{
+ ::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 )
+ {
+ // 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();
+ throw ParseError::Todo("block let");
+ GET_CHECK_TOK(tok, lex, TOK_SEMICOLON);
+ trailing_value = false;
+ 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;
+ }
+ break;
+ }
+ }
+ if( trailing_value == false )
+ {
+ nodes.push_back(ExprNode());
+ }
+ return AST::ExprNode(ExprNode::TagBlock(), nodes);
+}
+
+// 0: Assign
+AST::ExprNode Parse_Expr0(TokenStream& lex)
+{
+ AST::ExprNode rv = Parse_ExprBlocks(lex);
+ Token tok = lex.getToken();
+ if( tok.type() == TOK_EQUAL )
+ {
+ ExprNode val = Parse_Expr1(lex);
+ rv = ExprNode(ExprNode::TagAssign(), rv, val);
+ }
+ else
+ {
+ lex.putback(tok);
+ }
+ return rv;
+}
+
+// 0.5: Blocks
+AST::ExprNode Parse_ExprBlocks(TokenStream& lex)
+{
+ Token tok = lex.getToken();
+ switch( tok.type() )
+ {
+ case TOK_RWORD_MATCH:
+ throw ParseError::Todo("match");
+ break;
+ case TOK_RWORD_IF:
+ throw ParseError::Todo("if");
+ break;
+ default:
+ lex.putback(tok);
+ return Parse_Expr1(lex);
+ }
+}
+
+
+#define LEFTASSOC(cur, next, cases) \
+AST::ExprNode next(TokenStream& lex); \
+AST::ExprNode cur(TokenStream& lex) \
+{ \
+ ::std::cout << ">>" << #cur << ::std::endl; \
+ AST::ExprNode rv = next(lex); \
+ while(true) \
+ { \
+ Token tok; \
+ switch((tok = lex.getToken()).type()) \
+ { \
+ cases \
+ default: \
+ ::std::cout << "<<" << #cur << ::std::endl; \
+ lex.putback(tok); \
+ return rv; \
+ } \
+ } \
+}
+// 1: Bool OR
+LEFTASSOC(Parse_Expr1, Parse_Expr2,
+ case TOK_DOUBLE_PIPE:
+ throw ParseError::Todo("expr - boolean OR");
+)
+// 2: Bool AND
+LEFTASSOC(Parse_Expr2, Parse_Expr3,
+ case TOK_DOUBLE_AMP:
+ throw ParseError::Todo("expr - boolean AND");
+)
+// 3: (In)Equality
+LEFTASSOC(Parse_Expr3, Parse_Expr4,
+ case TOK_DOUBLE_EQUAL:
+ throw ParseError::Todo("expr - equal");
+ case TOK_EXLAM_EQUAL:
+ throw ParseError::Todo("expr - not equal");
+)
+// 4: Comparisons
+LEFTASSOC(Parse_Expr4, Parse_Expr5,
+ case TOK_LT:
+ throw ParseError::Todo("expr - less than");
+ case TOK_GT:
+ throw ParseError::Todo("expr - greater than");
+ case TOK_LTE:
+ throw ParseError::Todo("expr - less than or equal");
+ case TOK_GTE:
+ throw ParseError::Todo("expr - greater than or equal");
+)
+// 5: Bit OR
+LEFTASSOC(Parse_Expr5, Parse_Expr6,
+ case TOK_PIPE:
+ throw ParseError::Todo("expr - bitwise OR");
+)
+// 6: Bit XOR
+LEFTASSOC(Parse_Expr6, Parse_Expr7,
+ case TOK_CARET:
+ throw ParseError::Todo("expr - bitwise XOR");
+)
+// 7: Bit AND
+LEFTASSOC(Parse_Expr7, Parse_Expr8,
+ case TOK_AMP:
+ throw ParseError::Todo("expr - bitwise AND");
+)
+// 8: Bit Shifts
+LEFTASSOC(Parse_Expr8, Parse_Expr9,
+ case TOK_DOUBLE_LT:
+ throw ParseError::Todo("expr - shift left");
+ case TOK_DOUBLE_GT:
+ throw ParseError::Todo("expr - shift right");
+)
+// 9: Add / Subtract
+LEFTASSOC(Parse_Expr9, Parse_Expr10,
+ case TOK_PLUS:
+ throw ParseError::Todo("expr - add");
+ case TOK_DASH:
+ throw ParseError::Todo("expr - sub");
+)
+// 10: Cast
+LEFTASSOC(Parse_Expr10, Parse_Expr11,
+ case TOK_RWORD_AS:
+ throw ParseError::Todo("expr - cast");
+)
+// 11: Times / Divide / Modulo
+LEFTASSOC(Parse_Expr11, Parse_Expr12,
+ case TOK_STAR:
+ throw ParseError::Todo("expr - multiply");
+ case TOK_SLASH:
+ throw ParseError::Todo("expr - divide");
+ case TOK_PERCENT:
+ throw ParseError::Todo("expr - modulo");
+)
+// 12: Unaries
+AST::ExprNode Parse_ExprVal(TokenStream& lex);
+AST::ExprNode Parse_Expr12(TokenStream& lex)
+{
+ Token tok;
+ switch((tok = lex.getToken()).type())
+ {
+ case TOK_DASH:
+ throw ParseError::Todo("expr - negate");
+ case TOK_EXLAM:
+ throw ParseError::Todo("expr - logical negate");
+ case TOK_STAR:
+ throw ParseError::Todo("expr - dereference");
+ case TOK_RWORD_BOX:
+ throw ParseError::Todo("expr - box");
+ case TOK_AMP:
+ throw ParseError::Todo("expr - borrow");
+ default:
+ lex.putback(tok);
+ return Parse_ExprVal(lex);
+ }
+}
+
+AST::ExprNode Parse_ExprVal(TokenStream& lex)
+{
+ Token tok;
+ AST::Path path;
+ switch((tok = lex.getToken()).type())
+ {
+ case TOK_IDENT:
+ // Get path
+ lex.putback(tok);
+ path = Parse_Path(lex, false, true);
+ if(0)
+ case TOK_DOUBLE_COLON:
+ path = Parse_Path(lex, true, true);
+ switch( (tok = lex.getToken()).type() )
+ {
+ case TOK_BRACE_OPEN:
+ // Structure literal
+ throw ParseError::Todo("Structure literal");
+ break;
+ case TOK_PAREN_OPEN:
+ // Function call
+ throw ParseError::Todo("Function call");
+ break;
+ default:
+ // Value
+ lex.putback(tok);
+ throw ParseError::Todo("Variable/Constant");
+ }
+ case TOK_INTEGER:
+ return ExprNode(ExprNode::TagInteger(), tok.intval(), tok.datatype());
+ case TOK_FLOAT:
+ throw ParseError::Todo("Float");
+ default:
+ throw ParseError::Unexpected(tok);
+ }
+}
diff --git a/parse/root.cpp b/parse/root.cpp index 789d30b0..f78e9c1f 100644 --- a/parse/root.cpp +++ b/parse/root.cpp @@ -225,8 +225,7 @@ AST::Module Parse_ModRoot(bool is_own_file, Preproc& lex) is_mut = true;
tok = lex.getToken();
}
- if(tok.type() != TOK_IDENT)
- throw ParseError::Unexpected(tok, Token(TOK_IDENT));
+ CHECK_TOK(tok, TOK_IDENT);
::std::string name = tok.str();
GET_CHECK_TOK(tok, lex, TOK_COLON);
@@ -240,15 +239,64 @@ AST::Module Parse_ModRoot(bool is_own_file, Preproc& lex) mod.add_global(is_public, is_mut, name, type, val);
break; }
- case TOK_RWORD_FN:
- throw ParseError::Todo("modroot fn");
+ case TOK_RWORD_FN: {
+ GET_CHECK_TOK(tok, lex, TOK_IDENT);
+ ::std::string name = tok.str();
+ tok = lex.getToken();
+ AST::TypeParams params;
+ if( tok.type() == TOK_LT )
+ {
+ params = Parse_TypeParams(lex);
+ GET_CHECK_TOK(tok, lex, TOK_GT);
+ tok = lex.getToken();
+ if(tok.type() == TOK_RWORD_WHERE)
+ {
+ Parse_TypeConds(lex, params);
+ tok = lex.getToken();
+ }
+ }
+ CHECK_TOK(tok, TOK_PAREN_OPEN);
+ tok = lex.getToken();
+ ::std::vector<AST::StructItem> args;
+ if( tok.type() != TOK_PAREN_CLOSE )
+ {
+ // Argument list
+ lex.putback(tok);
+ do {
+ GET_CHECK_TOK(tok, lex, TOK_IDENT);
+ ::std::string name = tok.str();
+ GET_CHECK_TOK(tok, lex, TOK_COLON);
+ TypeRef type = Parse_Type(lex);
+ args.push_back( ::std::make_pair(name, type) );
+ tok = lex.getToken();
+ } while( tok.type() == TOK_COMMA );
+ CHECK_TOK(tok, TOK_PAREN_CLOSE);
+ }
+
+ TypeRef ret_type;
+ tok = lex.getToken();
+ if( tok.type() == TOK_THINARROW )
+ {
+ // Return type
+ ret_type = Parse_Type(lex);
+ }
+ else
+ {
+ lex.putback(tok);
+ }
+
+ AST::Expr code = Parse_ExprBlock(lex);
+
+ mod.add_function(is_public, name, params, ret_type, args, code);
+ break; }
case TOK_RWORD_STRUCT: {
GET_CHECK_TOK(tok, lex, TOK_IDENT);
::std::string name = tok.str();
tok = lex.getToken();
+ AST::TypeParams params;
if( tok.type() == TOK_LT )
{
- AST::TypeParams params = Parse_TypeParams(lex);
+ params = Parse_TypeParams(lex);
GET_CHECK_TOK(tok, lex, TOK_GT);
tok = lex.getToken();
if(tok.type() == TOK_RWORD_WHERE)
@@ -259,6 +307,20 @@ AST::Module Parse_ModRoot(bool is_own_file, Preproc& lex) }
if(tok.type() == TOK_PAREN_OPEN)
{
+ TypeRef inner = Parse_Type(lex);
+ tok = lex.getToken();
+ if(tok.type() != TOK_PAREN_CLOSE)
+ {
+ ::std::vector<TypeRef> refs;
+ refs.push_back(inner);
+ while( (tok = lex.getToken()).type() == TOK_COMMA )
+ {
+ refs.push_back( Parse_Type(lex) );
+ }
+ if( tok.type() != TOK_PAREN_CLOSE )
+ throw ParseError::Unexpected(tok, Token(TOK_PAREN_CLOSE));
+ inner = TypeRef(TypeRef::TagTuple(), refs);
+ }
throw ParseError::Todo("tuple struct");
}
else if(tok.type() == TOK_SEMICOLON)
@@ -267,14 +329,27 @@ AST::Module Parse_ModRoot(bool is_own_file, Preproc& lex) }
else if(tok.type() == TOK_BRACE_OPEN)
{
- throw ParseError::Todo("full struct");
+ ::std::vector<AST::StructItem> items;
+ while( (tok = lex.getToken()).type() != TOK_BRACE_CLOSE )
+ {
+ CHECK_TOK(tok, TOK_IDENT);
+ ::std::string name = tok.str();
+ GET_CHECK_TOK(tok, lex, TOK_COLON);
+ TypeRef type = Parse_Type(lex);
+ items.push_back( ::std::make_pair(name, type) );
+ tok = lex.getToken();
+ if(tok.type() == TOK_BRACE_CLOSE)
+ break;
+ if(tok.type() != TOK_COMMA)
+ throw ParseError::Unexpected(tok, Token(TOK_COMMA));
+ }
+ mod.add_struct(is_public, name, params, items);
}
else
{
throw ParseError::Unexpected(tok);
}
-
- throw ParseError::Todo("modroot struct"); }
+ break; }
case TOK_RWORD_ENUM:
throw ParseError::Todo("modroot enum");
case TOK_RWORD_IMPL:
|