From d2fae3b040b20c91afff472de5154977677d06c3 Mon Sep 17 00:00:00 2001 From: "John Hodge (bugs)" Date: Sun, 23 Nov 2014 21:18:03 +0800 Subject: Lexer "complete", parsing up to structure definitions. --- .gitignore | 2 + ast/ast.cpp | 37 ++++++++ ast/ast.hpp | 36 +++++++- coretypes.hpp | 18 ++++ mrustc.depend | 37 ++++++-- parse/common.hpp | 13 +++ parse/lex.cpp | 110 ++++++++++++++++++++-- parse/lex.hpp | 40 +++++++- parse/parseerror.hpp | 8 +- parse/preproc.cpp | 4 +- parse/root.cpp | 254 +++++++++++++++++++++++++++++++++++++++++++++++---- types.hpp | 32 +++++-- 12 files changed, 538 insertions(+), 53 deletions(-) create mode 100644 .gitignore create mode 100644 ast/ast.cpp create mode 100644 coretypes.hpp create mode 100644 parse/common.hpp diff --git a/.gitignore b/.gitignore new file mode 100644 index 00000000..fba4e61b --- /dev/null +++ b/.gitignore @@ -0,0 +1,2 @@ +/obj +/bin diff --git a/ast/ast.cpp b/ast/ast.cpp new file mode 100644 index 00000000..5c9c566e --- /dev/null +++ b/ast/ast.cpp @@ -0,0 +1,37 @@ +/* + */ +#include "ast.hpp" +#include "../types.hpp" +#include + +namespace AST { + +void Module::add_constant(bool is_public, ::std::string name, TypeRef type, Expr val) +{ + ::std::cout << "add_constant()" << ::std::endl; +} + +void Module::add_global(bool is_public, bool is_mut, ::std::string name, TypeRef type, Expr val) +{ + ::std::cout << "add_global()" << ::std::endl; +} + +ExprNode::ExprNode(TagInteger, uint64_t value, enum eCoreType datatype) +{ + +} + +TypeParam::TypeParam(bool is_lifetime, ::std::string name) +{ + +} +void TypeParam::addLifetimeBound(::std::string name) +{ + +} +void TypeParam::addTypeBound(TypeRef type) +{ + +} + +} diff --git a/ast/ast.hpp b/ast/ast.hpp index f637e742..f84f322f 100644 --- a/ast/ast.hpp +++ b/ast/ast.hpp @@ -1,6 +1,12 @@ #ifndef AST_HPP_INCLUDED #define AST_HPP_INCLUDED +#include +#include +#include "../coretypes.hpp" + +class TypeRef; + namespace AST { class Path @@ -9,10 +15,38 @@ public: void append(::std::string str) {} }; +class ExprNode +{ +public: + struct TagAssign {}; + ExprNode(TagAssign, ExprNode slot, ExprNode value) {} + struct TagInteger {}; + + ExprNode(TagInteger, uint64_t value, enum eCoreType datatype); +}; + +class Expr +{ +public: + Expr(ExprNode node) {} +}; + +class TypeParam +{ +public: + TypeParam(bool is_lifetime, ::std::string name); + void addLifetimeBound(::std::string name); + void addTypeBound(TypeRef type); +}; + +typedef ::std::vector TypeParams; + class Module { public: - void add_alias(Path path) {} + 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); }; } diff --git a/coretypes.hpp b/coretypes.hpp new file mode 100644 index 00000000..99d574b3 --- /dev/null +++ b/coretypes.hpp @@ -0,0 +1,18 @@ +#ifndef CORETYPES_HPP_INCLUDED +#define CORETYPES_HPP_INCLUDED + +enum eCoreType +{ + CORETYPE_INVAL, + CORETYPE_ANY, + CORETYPE_CHAR, + CORETYPE_UINT, CORETYPE_INT, + CORETYPE_U8, CORETYPE_I8, + CORETYPE_U16, CORETYPE_I16, + CORETYPE_U32, CORETYPE_I32, + CORETYPE_U64, CORETYPE_I64, + CORETYPE_F32, + CORETYPE_F64, +}; + +#endif // CORETYPES_HPP_INCLUDED diff --git a/mrustc.depend b/mrustc.depend index c38ae82f..591bf552 100644 --- a/mrustc.depend +++ b/mrustc.depend @@ -3,21 +3,24 @@ "parse/lex.hpp" -1416669570 source:c:\users\new\documents\code\mrustc\parse\lex.cpp +1416726665 source:c:\users\new\documents\code\mrustc\parse\lex.cpp "lex.hpp" "parseerror.hpp" -1416668008 c:\users\new\documents\code\mrustc\parse\lex.hpp +1416736249 c:\users\new\documents\code\mrustc\parse\lex.hpp "../types.hpp" -1416650017 c:\users\new\documents\code\mrustc\types.hpp +1416744265 c:\users\new\documents\code\mrustc\types.hpp + + "coretypes.hpp" + "ast/ast.hpp" -1416669842 c:\users\new\documents\code\mrustc\parse\parseerror.hpp +1416716101 c:\users\new\documents\code\mrustc\parse\parseerror.hpp "lex.hpp" @@ -25,18 +28,38 @@ "parseerror.hpp" -1416669782 source:c:\users\new\documents\code\mrustc\parse\preproc.cpp +1416715711 source:c:\users\new\documents\code\mrustc\parse\preproc.cpp "preproc.hpp" 1416668029 c:\users\new\documents\code\mrustc\parse\preproc.hpp "lex.hpp" -1416669832 source:c:\users\new\documents\code\mrustc\parse\root.cpp +1416748458 source:c:\users\new\documents\code\mrustc\parse\root.cpp "preproc.hpp" "../ast/ast.hpp" "parseerror.hpp" + "common.hpp" -1416669475 c:\users\new\documents\code\mrustc\ast\ast.hpp +1416748030 c:\users\new\documents\code\mrustc\ast\ast.hpp + + + "../coretypes.hpp" + +1416748091 source:c:\users\new\documents\code\mrustc\ast\ast.cpp + "ast.hpp" + "../types.hpp" + + +1416731433 c:\users\new\documents\code\mrustc\parse\common.hpp + +1416739817 source:c:\users\new\documents\code\mrustc\parse\expr.cpp + "preproc.hpp" + "parseerror.hpp" + "../ast/ast.hpp" + "common.hpp" + + +1416737315 c:\users\new\documents\code\mrustc\coretypes.hpp diff --git a/parse/common.hpp b/parse/common.hpp new file mode 100644 index 00000000..357944c4 --- /dev/null +++ b/parse/common.hpp @@ -0,0 +1,13 @@ +#ifndef PARSE_COMMON_HPP_INCLUDED +#define PARSEERROR_HPP_INCLUDED + +#define GET_CHECK_TOK(tok, lex, exp) do {\ + if((tok = lex.getToken()).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); + +#endif // PARSE_COMMON_HPP_INCLUDED diff --git a/parse/lex.cpp b/parse/lex.cpp index cbd753f8..2c6d42df 100644 --- a/parse/lex.cpp +++ b/parse/lex.cpp @@ -28,7 +28,7 @@ Lexer::Lexer(::std::string filename): // NOTE: This array must be kept reverse sorted #define TOKENT(str, sym) {sizeof(str)-1, str, sym} -const struct { +static const struct { unsigned char len; const char* chars; signed int type; @@ -85,13 +85,6 @@ const struct { TOKENT("^", TOK_CARET), TOKENT("`", TOK_BACKTICK), - TOKENT("as", TOK_RWORD_AS), - TOKENT("const", TOK_RWORD_CONST), - TOKENT("fn", TOK_RWORD_FN), - TOKENT("for", TOK_RWORD_FOR), - TOKENT("static",TOK_RWORD_STATIC), - TOKENT("use", TOK_RWORD_USE), - TOKENT("{", TOK_BRACE_OPEN), TOKENT("|", TOK_PIPE), TOKENT("|=", TOK_PIPE_EQUAL), @@ -100,6 +93,63 @@ const struct { TOKENT("~", TOK_TILDE), }; #define LEN(arr) (sizeof(arr)/sizeof(arr[0])) +static const struct { + unsigned char len; + const char* chars; + signed int type; +} RWORDS[] = { + TOKENT("abstract",TOK_RWORD_ABSTRACT), + TOKENT("alignof", TOK_RWORD_ALIGNOF), + TOKENT("as", TOK_RWORD_AS), + TOKENT("be", TOK_RWORD_BE), + TOKENT("box", TOK_RWORD_BOX), + TOKENT("break", TOK_RWORD_BREAK), + TOKENT("const", TOK_RWORD_CONST), + TOKENT("continue",TOK_RWORD_CONTINUE), + TOKENT("crate", TOK_RWORD_CRATE), + TOKENT("do", TOK_RWORD_DO), + TOKENT("else", TOK_RWORD_ELSE), + TOKENT("enum", TOK_RWORD_ENUM), + TOKENT("extern", TOK_RWORD_EXTERN), + TOKENT("false", TOK_RWORD_FALSE), + TOKENT("final", TOK_RWORD_FINAL), + TOKENT("fn", TOK_RWORD_FN), + TOKENT("for", TOK_RWORD_FOR), + TOKENT("if", TOK_RWORD_IF), + TOKENT("impl", TOK_RWORD_IMPL), + TOKENT("in", TOK_RWORD_IN), + TOKENT("let", TOK_RWORD_LET), + TOKENT("loop", TOK_RWORD_LOOP), + TOKENT("match", TOK_RWORD_MATCH), + TOKENT("mod", TOK_RWORD_MOD), + TOKENT("move", TOK_RWORD_MOVE), + TOKENT("mut", TOK_RWORD_MUT), + TOKENT("offsetof",TOK_RWORD_OFFSETOF), + TOKENT("once", TOK_RWORD_ONCE), + TOKENT("override",TOK_RWORD_OVERRIDE), + TOKENT("priv", TOK_RWORD_PRIV), + TOKENT("proc", TOK_RWORD_PROC), + TOKENT("pub", TOK_RWORD_PUB), + TOKENT("pure", TOK_RWORD_PURE), + TOKENT("ref", TOK_RWORD_REF), + TOKENT("return", TOK_RWORD_RETURN), + TOKENT("sizeof", TOK_RWORD_SIZEOF), + TOKENT("static", TOK_RWORD_STATIC), + TOKENT("self", TOK_RWORD_SELF), + TOKENT("struct", TOK_RWORD_STRUCT), + TOKENT("super", TOK_RWORD_SUPER), + TOKENT("true", TOK_RWORD_TRUE), + TOKENT("trait", TOK_RWORD_TRAIT), + TOKENT("type", TOK_RWORD_TYPE), + TOKENT("typeof", TOK_RWORD_TYPEOF), + TOKENT("unsafe", TOK_RWORD_UNSAFE), + TOKENT("unsized", TOK_RWORD_UNSIZED), + TOKENT("use", TOK_RWORD_USE), + TOKENT("virtual", TOK_RWORD_VIRTUAL), + TOKENT("where", TOK_RWORD_WHERE), + TOKENT("while", TOK_RWORD_WHILE), + TOKENT("yield", TOK_RWORD_YIELD), +}; signed int Lexer::getSymbol() { @@ -183,6 +233,11 @@ Token Lexer::getToken() } else { + for( unsigned int i = 0; i < LEN(RWORDS); i ++ ) + { + if( str < RWORDS[i].chars ) break; + if( str == RWORDS[i].chars ) return Token((enum eTokenType)RWORDS[i].type); + } return Token(TOK_IDENT, str); } } @@ -311,7 +366,7 @@ char Lexer::getc() if( m_istream.eof() ) throw Lexer::EndOfFile(); } -// ::std::cout << "getc(): '" << m_last_char << "'" << ::std::endl; + //::std::cout << "getc(): '" << m_last_char << "'" << ::std::endl; return m_last_char; } @@ -418,30 +473,65 @@ const char* Token::typestr(enum eTokenType type) // Reserved Words case TOK_RWORD_PUB: return "TOK_RWORD_PUB"; + case TOK_RWORD_PRIV: return "TOK_RWORD_PRIV"; case TOK_RWORD_MUT: return "TOK_RWORD_MUT"; case TOK_RWORD_CONST: return "TOK_RWORD_CONST"; case TOK_RWORD_STATIC: return "TOK_RWORD_STATIC"; case TOK_RWORD_UNSAFE: return "TOK_RWORD_UNSAFE"; + case TOK_RWORD_EXTERN: return "TOK_RWORD_EXTERN"; + case TOK_RWORD_CRATE: return "TOK_RWORD_CRATE"; + case TOK_RWORD_MOD: return "TOK_RWORD_MOD"; case TOK_RWORD_STRUCT: return "TOK_RWORD_STRUCT"; case TOK_RWORD_ENUM: return "TOK_RWORD_ENUM"; case TOK_RWORD_TRAIT: return "TOK_RWORD_TRAIT"; case TOK_RWORD_FN: return "TOK_RWORD_FN"; case TOK_RWORD_USE: return "TOK_RWORD_USE"; + case TOK_RWORD_IMPL: return "TOK_RWORD_IMPL"; + case TOK_RWORD_TYPE: return "TOK_RWORD_TYPE"; - case TOK_RWORD_SELF: return "TOK_RWORD_SELF"; + case TOK_RWORD_WHERE: return "TOK_RWORD_WHERE"; case TOK_RWORD_AS: return "TOK_RWORD_AS"; case TOK_RWORD_LET: return "TOK_RWORD_LET"; case TOK_RWORD_MATCH: return "TOK_RWORD_MATCH"; case TOK_RWORD_IF: return "TOK_RWORD_IF"; case TOK_RWORD_ELSE: return "TOK_RWORD_ELSE"; + case TOK_RWORD_LOOP: return "TOK_RWORD_LOOP"; case TOK_RWORD_WHILE: return "TOK_RWORD_WHILE"; case TOK_RWORD_FOR: return "TOK_RWORD_FOR"; + case TOK_RWORD_IN: return "TOK_RWORD_IN"; + case TOK_RWORD_DO: return "TOK_RWORD_DO"; case TOK_RWORD_CONTINUE: return "TOK_RWORD_CONTINUE"; case TOK_RWORD_BREAK: return "TOK_RWORD_BREAK"; case TOK_RWORD_RETURN: return "TOK_RWORD_RETURN"; + case TOK_RWORD_YIELD: return "TOK_RWORD_YIELD"; + case TOK_RWORD_BOX: return "TOK_RWORD_BOX"; + case TOK_RWORD_REF: return "TOK_RWORD_REF"; + + case TOK_RWORD_FALSE: return "TOK_RWORD_FALSE"; + case TOK_RWORD_TRUE: return "TOK_RWORD_TRUE"; + case TOK_RWORD_SELF: return "TOK_RWORD_SELF"; + case TOK_RWORD_SUPER: return "TOK_RWORD_SUPER"; + + case TOK_RWORD_PROC: return "TOK_RWORD_PROC"; + case TOK_RWORD_MOVE: return "TOK_RWORD_MOVE"; + case TOK_RWORD_ONCE: return "TOK_RWORD_ONCE"; + + case TOK_RWORD_ABSTRACT: return "TOK_RWORD_ABSTRACT"; + case TOK_RWORD_FINAL: return "TOK_RWORD_FINAL"; + case TOK_RWORD_PURE: return "TOK_RWORD_PURE"; + case TOK_RWORD_OVERRIDE: return "TOK_RWORD_OVERRIDE"; + case TOK_RWORD_VIRTUAL: return "TOK_RWORD_VIRTUAL"; + + case TOK_RWORD_ALIGNOF: return "TOK_RWORD_ALIGNOF"; + case TOK_RWORD_OFFSETOF: return "TOK_RWORD_OFFSETOF"; + case TOK_RWORD_SIZEOF: return "TOK_RWORD_SIZEOF"; + case TOK_RWORD_TYPEOF: return "TOK_RWORD_TYPEOF"; + + case TOK_RWORD_BE: return "TOK_RWORD_BE"; + case TOK_RWORD_UNSIZED: return "TOK_RWORD_UNSIZED"; } return ">>BUGCHECK: BADTOK<<"; } diff --git a/parse/lex.hpp b/parse/lex.hpp index 5e3d2dd4..3dff4d3a 100644 --- a/parse/lex.hpp +++ b/parse/lex.hpp @@ -77,30 +77,65 @@ enum eTokenType // Reserved Words TOK_RWORD_PUB, + TOK_RWORD_PRIV, TOK_RWORD_MUT, TOK_RWORD_CONST, TOK_RWORD_STATIC, TOK_RWORD_UNSAFE, + TOK_RWORD_EXTERN, + TOK_RWORD_CRATE, + TOK_RWORD_MOD, TOK_RWORD_STRUCT, TOK_RWORD_ENUM, TOK_RWORD_TRAIT, TOK_RWORD_FN, TOK_RWORD_USE, + TOK_RWORD_IMPL, + TOK_RWORD_TYPE, - TOK_RWORD_SELF, + TOK_RWORD_WHERE, TOK_RWORD_AS, TOK_RWORD_LET, TOK_RWORD_MATCH, TOK_RWORD_IF, TOK_RWORD_ELSE, + TOK_RWORD_LOOP, TOK_RWORD_WHILE, TOK_RWORD_FOR, + TOK_RWORD_IN, + TOK_RWORD_DO, TOK_RWORD_CONTINUE, TOK_RWORD_BREAK, TOK_RWORD_RETURN, + TOK_RWORD_YIELD, + TOK_RWORD_BOX, + TOK_RWORD_REF, + + TOK_RWORD_FALSE, + TOK_RWORD_TRUE, + TOK_RWORD_SELF, + TOK_RWORD_SUPER, + + TOK_RWORD_PROC, + TOK_RWORD_MOVE, + TOK_RWORD_ONCE, + + TOK_RWORD_ABSTRACT, + TOK_RWORD_FINAL, + TOK_RWORD_PURE, + TOK_RWORD_OVERRIDE, + TOK_RWORD_VIRTUAL, + + TOK_RWORD_ALIGNOF, + TOK_RWORD_OFFSETOF, + TOK_RWORD_SIZEOF, + TOK_RWORD_TYPEOF, + + TOK_RWORD_BE, + TOK_RWORD_UNSIZED, }; class Token @@ -121,6 +156,9 @@ public: enum eTokenType type() { return m_type; } const ::std::string& str() { return m_str; } + enum eCoreType datatype() { return m_datatype; } + uint64_t intval() { return m_intval; } + double floatval() { return m_floatval; } static const char* typestr(enum eTokenType type); }; diff --git a/parse/parseerror.hpp b/parse/parseerror.hpp index 487c1a6e..b708565d 100644 --- a/parse/parseerror.hpp +++ b/parse/parseerror.hpp @@ -10,7 +10,7 @@ class Base: public ::std::exception { public: - ~Base() throw(); + virtual ~Base() throw(); }; class Todo: @@ -19,7 +19,7 @@ class Todo: ::std::string m_message; public: Todo(::std::string message); - ~Todo() throw (); + virtual ~Todo() throw (); }; @@ -29,7 +29,7 @@ class BadChar: char m_char; public: BadChar(char character); - ~BadChar() throw (); + virtual ~BadChar() throw (); }; @@ -40,7 +40,7 @@ class Unexpected: public: Unexpected(Token tok); Unexpected(Token tok, Token exp); - ~Unexpected() throw (); + virtual ~Unexpected() throw (); }; diff --git a/parse/preproc.cpp b/parse/preproc.cpp index ec64d731..fa051a3e 100644 --- a/parse/preproc.cpp +++ b/parse/preproc.cpp @@ -2,8 +2,8 @@ #include Preproc::Preproc(::std::string path): - m_cache_valid(false), - m_lex(path) + m_lex(path), + m_cache_valid(false) { //ctor } diff --git a/parse/root.cpp b/parse/root.cpp index 620a1fce..789d30b0 100644 --- a/parse/root.cpp +++ b/parse/root.cpp @@ -3,24 +3,180 @@ #include "preproc.hpp" #include "../ast/ast.hpp" #include "parseerror.hpp" +#include "common.hpp" #include -AST::Path Parse_Path(TokenStream& lex) +AST::Path Parse_Path(TokenStream& lex, bool is_abs, bool generic_ok) { AST::Path path; - for(;;) + Token tok; + do { - Token tok = lex.getToken(); + tok = lex.getToken(); + if(tok.type() == TOK_LT) + { + throw ParseError::Todo("Parse_Path - Generics"); + } + if(tok.type() != TOK_IDENT) throw ParseError::Unexpected(tok); path.append( tok.str() ); tok = lex.getToken(); - if(tok.type() != TOK_DOUBLE_COLON) { + } while( tok.type() == TOK_DOUBLE_COLON ); + lex.putback(tok); + return path; +} + +static const struct { + const char* name; + enum eCoreType type; +} CORETYPES[] = { + {"char", CORETYPE_CHAR}, + {"uint", CORETYPE_UINT}, + {"int", CORETYPE_INT}, + {"u8", CORETYPE_U8}, + {"i8", CORETYPE_I8}, + {"u16", CORETYPE_U16}, + {"i16", CORETYPE_I16}, + {"u32", CORETYPE_U32}, + {"i32", CORETYPE_I32}, + {"u64", CORETYPE_U64}, + {"i64", CORETYPE_I64}, + {"f32", CORETYPE_F32}, + {"f64", CORETYPE_F64} +}; + +TypeRef Parse_Type(TokenStream& lex) +{ + Token tok = lex.getToken(); + switch(tok.type()) + { + case TOK_IDENT: + // Either a path (with generics) + if( tok.str() == "_" ) + return TypeRef(); + for(unsigned int i = 0; i < sizeof(CORETYPES)/sizeof(CORETYPES[0]); i ++) + { + if( tok.str() < CORETYPES[i].name ) + break; + if( tok.str() == CORETYPES[i].name ) + return TypeRef(TypeRef::TagPrimitive(), CORETYPES[i].type); + } + // or a primitive + lex.putback(tok); + return TypeRef(TypeRef::TagPath(), Parse_Path(lex, false, true)); // relative path + case TOK_DOUBLE_COLON: + // Path with generics + //return TypeRef(TypeRef::TagPath(), Parse_Path(lex, true, true)); + throw ParseError::Todo("type ::"); + case TOK_AMP: + // Reference + tok = lex.getToken(); + if( tok.type() == TOK_RWORD_MUT ) { + // Mutable reference + return TypeRef(TypeRef::TagReference(), true, Parse_Type(lex)); + } + else { lex.putback(tok); - break; + // Immutable reference + return TypeRef(TypeRef::TagReference(), false, Parse_Type(lex)); + } + break; + case TOK_STAR: + // Pointer + tok = lex.getToken(); + switch( tok.type() ) + { + case TOK_RWORD_MUT: + // Mutable pointer + return TypeRef(TypeRef::TagPointer(), true, Parse_Type(lex)); + case TOK_RWORD_CONST: + // Immutable pointer + return TypeRef(TypeRef::TagPointer(), false, Parse_Type(lex)); + default: + throw ParseError::Unexpected(tok, Token(TOK_RWORD_CONST)); } + break; + case TOK_SQUARE_OPEN: { + // Array + TypeRef inner = Parse_Type(lex); + tok = lex.getToken(); + if( tok.type() == TOK_COMMA ) { + // Sized array + GET_CHECK_TOK(tok, lex, TOK_DOUBLE_DOT); + AST::Expr array_size = Parse_Expr(lex, true); + GET_CHECK_TOK(tok, lex, TOK_SQUARE_CLOSE); + return TypeRef(TypeRef::TagSizedArray(), inner, array_size); + } + else { + GET_CHECK_TOK(tok, lex, TOK_SQUARE_CLOSE); + return TypeRef(TypeRef::TagUnsizedArray(), inner); + } + break; } + case TOK_PAREN_OPEN: { + ::std::vector types; + if( (tok = lex.getToken()).type() == TOK_PAREN_CLOSE) + return TypeRef(TypeRef::TagTuple(), types); + do + { + TypeRef type = Parse_Type(lex); + types.push_back(type); + } while( (tok = lex.getToken()).type() == TOK_COMMA ); + GET_CHECK_TOK(tok, lex, TOK_PAREN_CLOSE); + return TypeRef(TypeRef::TagTuple(), types); } + default: + throw ParseError::Unexpected(tok); } - return path; +} + +AST::TypeParams Parse_TypeParams(TokenStream& lex) +{ + AST::TypeParams ret; + Token tok; + do { + bool is_lifetime = false; + tok = lex.getToken(); + switch(tok.type()) + { + case TOK_IDENT: + break; + case TOK_LIFETIME: + is_lifetime = true; + break; + default: + // Oopsie! + throw ParseError::Unexpected(tok); + } + AST::TypeParam param( is_lifetime, tok.str() ); + tok = lex.getToken(); + if( tok.type() == TOK_COLON ) + { + // TODO: Conditions + if( is_lifetime ) + { + throw ParseError::Todo("lifetime param conditions"); + } + + do { + tok = lex.getToken(); + if(tok.type() == TOK_LIFETIME) + param.addLifetimeBound(tok.str()); + else { + lex.putback(tok); + param.addTypeBound(Parse_Type(lex)); + } + tok = lex.getToken(); + } while(tok.type() == TOK_PLUS); + } + ret.push_back(param); + } while( tok.type() == TOK_COMMA ); + lex.putback(tok); + return ret; +} + +void Parse_TypeConds(TokenStream& lex, AST::TypeParams& params) +{ + throw ParseError::Todo("type param conditions (where)"); } AST::Module Parse_ModRoot(bool is_own_file, Preproc& lex) @@ -47,22 +203,84 @@ AST::Module Parse_ModRoot(bool is_own_file, Preproc& lex) break; case TOK_RWORD_USE: - mod.add_alias( Parse_Path(lex) ); - tok = lex.getToken(); - if( tok.type() != TOK_SEMICOLON ) - throw ParseError::Unexpected(tok, Token(TOK_SEMICOLON)); + mod.add_alias( is_public, Parse_Path(lex, true, false) ); + GET_CHECK_TOK(tok, lex, TOK_SEMICOLON); break; - case TOK_RWORD_CONST: - //mod.add_constant(is_public, name, type, value); - throw ParseError::Todo("modroot const"); - case TOK_RWORD_STATIC: - //mod.add_global(is_public, is_mut, name, type, value); - throw ParseError::Todo("modroot static"); + case TOK_RWORD_CONST: { + GET_CHECK_TOK(tok, lex, TOK_IDENT); + ::std::string name = tok.str(); + + GET_CHECK_TOK(tok, lex, TOK_COLON); + TypeRef type = Parse_Type(lex); + GET_CHECK_TOK(tok, lex, TOK_EQUAL); + AST::Expr val = Parse_Expr(lex, true); + GET_CHECK_TOK(tok, lex, TOK_SEMICOLON); + mod.add_constant(is_public, name, type, val); + break; } + case TOK_RWORD_STATIC: { + tok = lex.getToken(); + bool is_mut = false; + if(tok.type() == TOK_RWORD_MUT) { + is_mut = true; + tok = lex.getToken(); + } + if(tok.type() != TOK_IDENT) + throw ParseError::Unexpected(tok, Token(TOK_IDENT)); + ::std::string name = tok.str(); + + GET_CHECK_TOK(tok, lex, TOK_COLON); + TypeRef type = Parse_Type(lex); + + GET_CHECK_TOK(tok, lex, TOK_EQUAL); + + AST::Expr val = Parse_Expr(lex, true); + + GET_CHECK_TOK(tok, lex, TOK_SEMICOLON); + mod.add_global(is_public, is_mut, name, type, val); + break; } + case TOK_RWORD_FN: throw ParseError::Todo("modroot fn"); - case TOK_RWORD_STRUCT: - throw ParseError::Todo("modroot struct"); + case TOK_RWORD_STRUCT: { + GET_CHECK_TOK(tok, lex, TOK_IDENT); + ::std::string name = tok.str(); + tok = lex.getToken(); + if( tok.type() == TOK_LT ) + { + AST::TypeParams 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(); + } + } + if(tok.type() == TOK_PAREN_OPEN) + { + throw ParseError::Todo("tuple struct"); + } + else if(tok.type() == TOK_SEMICOLON) + { + throw ParseError::Todo("unit-like struct"); + } + else if(tok.type() == TOK_BRACE_OPEN) + { + throw ParseError::Todo("full struct"); + } + else + { + throw ParseError::Unexpected(tok); + } + + throw ParseError::Todo("modroot struct"); } + case TOK_RWORD_ENUM: + throw ParseError::Todo("modroot enum"); + case TOK_RWORD_IMPL: + throw ParseError::Todo("modroot impl"); + case TOK_RWORD_TRAIT: + throw ParseError::Todo("modroot trait"); default: throw ParseError::Unexpected(tok); diff --git a/types.hpp b/types.hpp index b5971602..0f5ec42f 100644 --- a/types.hpp +++ b/types.hpp @@ -1,17 +1,29 @@ #ifndef TYPES_HPP_INCLUDED #define TYPES_HPP_INCLUDED -enum eCoreType +#include +#include "coretypes.hpp" +#include "ast/ast.hpp" + +class TypeRef { - CORETYPE_ANY, - CORETYPE_CHAR, - CORETYPE_UINT, CORETYPE_INT, - CORETYPE_U8, CORETYPE_I8, - CORETYPE_U16, CORETYPE_I16, - CORETYPE_U32, CORETYPE_I32, - CORETYPE_U64, CORETYPE_I64, - CORETYPE_f32, - CORETYPE_f64, +public: + TypeRef() {} + struct TagPrimitive {}; + TypeRef(TagPrimitive, enum eCoreType type) {} + struct TagTuple {}; + TypeRef(TagTuple _, ::std::vector inner_types) {} + struct TagReference {}; + TypeRef(TagReference _, bool is_mut, TypeRef inner_type) {} + struct TagPointer {}; + TypeRef(TagPointer _, bool is_mut, TypeRef inner_type) {} + struct TagSizedArray {}; + TypeRef(TagSizedArray _, TypeRef inner_type, AST::Expr size) {} + struct TagUnsizedArray {}; + TypeRef(TagUnsizedArray _, TypeRef inner_type) {} + + struct TagPath {}; + TypeRef(TagPath, AST::Path path) {} }; #endif // TYPES_HPP_INCLUDED -- cgit v1.2.3