Browse Source

Merge remote-tracking branch 'upstream/master' into fix-issue-345

Jeroen van Rijn 6 years ago
parent
commit
a126d2ba16
4 changed files with 46 additions and 12 deletions
  1. 1 5
      core/odin/parser/parser.odin
  2. 23 5
      core/odin/token/token.odin
  3. 8 2
      core/odin/tokenizer/tokenizer.odin
  4. 14 0
      core/os/os.odin

+ 1 - 5
core/odin/parser/parser.odin

@@ -857,10 +857,6 @@ parse_foreign_block :: proc(p: ^Parser, tok: token.Token) -> ^ast.Foreign_Block_
 
 	foreign_library: ^ast.Expr;
 	switch p.curr_tok.kind {
-	case token.Export:
-		i := ast.new(ast.Implicit, tok.pos, end_pos(tok));
-		i.tok = expect_token(p, token.Export);
-		foreign_library = i;
 	case token.Open_Brace:
 		i := ast.new(ast.Ident, tok.pos, end_pos(tok));
 		i.name = "_";
@@ -903,7 +899,7 @@ parse_foreign_decl :: proc(p: ^Parser) -> ^ast.Decl {
 	tok := expect_token(p, token.Foreign);
 
 	switch p.curr_tok.kind {
-	case token.Export, token.Ident, token.Open_Brace:
+	case token.Ident, token.Open_Brace:
 		return parse_foreign_block(p, tok);
 
 	case token.Import:

+ 23 - 5
core/odin/token/token.odin

@@ -28,7 +28,7 @@ pos_compare :: proc(lhs, rhs: Pos) -> int {
 	return strings.compare(lhs.file, rhs.file);
 }
 
-using Kind :: enum u16 {
+using Kind :: enum u32 {
 	Invalid,
 	EOF,
 	Comment,
@@ -113,7 +113,6 @@ using Kind :: enum u16 {
 
 	B_Keyword_Begin,
 		Import,
-		Export,
 		Foreign,
 		Package,
 		Typeid,
@@ -160,6 +159,9 @@ using Kind :: enum u16 {
 	B_Keyword_End,
 
 	COUNT,
+
+	B_Custom_Keyword_Begin = COUNT+1,
+	// ... Custom keywords
 };
 
 tokens := [Kind.COUNT]string {
@@ -247,7 +249,6 @@ tokens := [Kind.COUNT]string {
 
 	"",
 	"import",
-	"export",
 	"foreign",
 	"package",
 	"typeid",
@@ -294,10 +295,19 @@ tokens := [Kind.COUNT]string {
 	"",
 };
 
+custom_keyword_tokens: []string;
+
 to_string :: proc(kind: Kind) -> string {
-	if min(Kind) <= kind && kind <= max(Kind) {
+	if Invalid <= kind && kind < COUNT {
 		return tokens[kind];
 	}
+	if B_Custom_Keyword_Begin < kind {
+		n := int(u16(kind)-u16(B_Custom_Keyword_Begin));
+		if n < len(custom_keyword_tokens) {
+			return custom_keyword_tokens[n];
+		}
+	}
+
 	return "Invalid";
 }
 
@@ -314,4 +324,12 @@ is_operator :: proc(kind: Kind) -> bool {
 is_assignment_operator :: proc(kind: Kind) -> bool {
 	return B_Assign_Op_Begin < kind && kind < B_Assign_Op_End || kind == Eq;
 }
-is_keyword :: proc(kind: Kind) -> bool { return B_Keyword_Begin  < kind && kind < B_Keyword_End;  }
+is_keyword :: proc(kind: Kind) -> bool {
+	switch {
+	case B_Keyword_Begin < kind && kind < B_Keyword_End:
+		return true;
+	case B_Custom_Keyword_Begin < kind:
+		return true;
+	}
+	return false;
+}

+ 8 - 2
core/odin/tokenizer/tokenizer.odin

@@ -486,12 +486,18 @@ scan :: proc(t: ^Tokenizer) -> token.Token {
 	case is_letter(ch):
 		lit = scan_identifier(t);
 		kind = token.Ident;
-		if len(lit) > 1 {
+		check_keyword: if len(lit) > 1 {
 			// TODO(bill): Maybe have a hash table lookup rather than this linear search
 			for i in token.B_Keyword_Begin .. token.B_Keyword_End {
 				if lit == token.tokens[i] {
 					kind = token.Kind(i);
-					break;
+					break check_keyword;
+				}
+			}
+			for keyword, i in token.custom_keyword_tokens {
+				if lit == keyword {
+					kind = token.Kind(i+1)+token.B_Custom_Keyword_Begin;
+					break check_keyword;
 				}
 			}
 		}

+ 14 - 0
core/os/os.odin

@@ -51,6 +51,20 @@ write_encoded_rune :: proc(fd: Handle, r: rune) {
 }
 
 
+file_size_from_path :: proc(path: string) -> i64 {
+	fd, err := open(path, O_RDONLY, 0);
+	if err != 0 {
+		return -1;
+	}
+	defer close(fd);
+
+	length: i64;
+	if length, err = file_size(fd); err != 0 {
+		return -1;
+	}
+	return length;
+}
+
 read_entire_file :: proc(name: string) -> (data: []byte, success: bool) {
 	fd, err := open(name, O_RDONLY, 0);
 	if err != 0 {