summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--.gitignore2
-rw-r--r--ast/ast.cpp37
-rw-r--r--ast/ast.hpp36
-rw-r--r--coretypes.hpp18
-rw-r--r--mrustc.depend37
-rw-r--r--parse/common.hpp13
-rw-r--r--parse/lex.cpp110
-rw-r--r--parse/lex.hpp40
-rw-r--r--parse/parseerror.hpp8
-rw-r--r--parse/preproc.cpp4
-rw-r--r--parse/root.cpp254
-rw-r--r--types.hpp32
12 files changed, 538 insertions, 53 deletions
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 <iostream>
+
+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 <string>
+#include <vector>
+#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<TypeParam> 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 @@
<iostream>
"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"
<cassert>
<iostream>
<cstdlib>
-1416668008 c:\users\new\documents\code\mrustc\parse\lex.hpp
+1416736249 c:\users\new\documents\code\mrustc\parse\lex.hpp
"../types.hpp"
<string>
<fstream>
-1416650017 c:\users\new\documents\code\mrustc\types.hpp
+1416744265 c:\users\new\documents\code\mrustc\types.hpp
+ <vector>
+ "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
<stdexcept>
"lex.hpp"
@@ -25,18 +28,38 @@
"parseerror.hpp"
<iostream>
-1416669782 source:c:\users\new\documents\code\mrustc\parse\preproc.cpp
+1416715711 source:c:\users\new\documents\code\mrustc\parse\preproc.cpp
"preproc.hpp"
<iostream>
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"
<cassert>
-1416669475 c:\users\new\documents\code\mrustc\ast\ast.hpp
+1416748030 c:\users\new\documents\code\mrustc\ast\ast.hpp
+ <string>
+ <vector>
+ "../coretypes.hpp"
+
+1416748091 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
+
+1416739817 source:c:\users\new\documents\code\mrustc\parse\expr.cpp
+ "preproc.hpp"
+ "parseerror.hpp"
+ "../ast/ast.hpp"
+ "common.hpp"
+ <iostream>
+
+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 <iostream>
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 <cassert>
-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<TypeRef> 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 <vector>
+#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<TypeRef> 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