Lexer tokens are now created by the lexer
This is so positional information can be accurately embedded into them.
This commit is contained in:
		
							parent
							
								
									accf528869
								
							
						
					
					
						commit
						856d5763d3
					
				| @ -103,11 +103,11 @@ func (file *File) Close () { | ||||
| 
 | ||||
| // Location returns a location struct describing the current position inside of | ||||
| // the file. This can be stored and used to print errors. | ||||
| func (file *File) Location () (location Location) { | ||||
| func (file *File) Location (width int) (location Location) { | ||||
| 	return Location { | ||||
| 		file:   file, | ||||
| 		row:    file.currentLine, | ||||
| 		column: file.currentColumn, | ||||
| 		width:  1, | ||||
| 		width:  width, | ||||
| 	} | ||||
| } | ||||
|  | ||||
							
								
								
									
										135
									
								
								lexer/lexer.go
									
									
									
									
									
								
							
							
						
						
									
										135
									
								
								lexer/lexer.go
									
									
									
									
									
								
							| @ -35,7 +35,7 @@ func (lexer *LexingOperation) tokenize () (err error) { | ||||
| 		 | ||||
| 		if err != nil || shebangCheck[index] != lexer.char { | ||||
| 			err = file.NewError ( | ||||
| 				lexer.file.Location(), | ||||
| 				lexer.file.Location(1), | ||||
| 				"not an arf file", | ||||
| 				file.ErrorKindError) | ||||
| 			return | ||||
| @ -66,13 +66,18 @@ func (lexer *LexingOperation) tokenize () (err error) { | ||||
| 	} | ||||
| 
 | ||||
| 	if lexer.tokens[len(lexer.tokens) - 1].kind != TokenKindNewline { | ||||
| 		lexer.addToken(Token { kind: TokenKindNewline }) | ||||
| 		token := lexer.newToken() | ||||
| 		token.kind = TokenKindNewline | ||||
| 		lexer.addToken(token) | ||||
| 	} | ||||
| 
 | ||||
| 	return | ||||
| } | ||||
| 
 | ||||
| func (lexer *LexingOperation) tokenizeAlphaBeginning () (err error) { | ||||
| 	token := lexer.newToken() | ||||
| 	token.kind = TokenKindName | ||||
| 
 | ||||
| 	got := "" | ||||
| 
 | ||||
| 	for { | ||||
| @ -86,7 +91,7 @@ func (lexer *LexingOperation) tokenizeAlphaBeginning () (err error) { | ||||
| 		lexer.nextRune() | ||||
| 	} | ||||
| 
 | ||||
| 	token := Token { kind: TokenKindName, value: got } | ||||
| 	token.value = got | ||||
| 
 | ||||
| 	if len(got) == 2 { | ||||
| 		firstValid  := got[0] == 'n' || got[0] == 'r' || got[0] == 'w' | ||||
| @ -119,11 +124,14 @@ func (lexer *LexingOperation) tokenizeSymbolBeginning () (err error) { | ||||
| 			err = lexer.nextRune() | ||||
| 			 | ||||
| 			file.NewError ( | ||||
| 				lexer.file.Location(), | ||||
| 				lexer.file.Location(1), | ||||
| 				"tab not used as indent", | ||||
| 				file.ErrorKindWarn).Print() | ||||
| 			return | ||||
| 		} | ||||
| 		 | ||||
| 		token := lexer.newToken() | ||||
| 		token.kind = TokenKindIndent | ||||
| 
 | ||||
| 		// eat up tabs while increasing the indent level | ||||
| 		indentLevel := 0		 | ||||
| @ -132,11 +140,9 @@ func (lexer *LexingOperation) tokenizeSymbolBeginning () (err error) { | ||||
| 			err = lexer.nextRune() | ||||
| 			if err != nil { return } | ||||
| 		} | ||||
| 		 | ||||
| 		lexer.addToken (Token { | ||||
| 			kind: TokenKindIndent, | ||||
| 			value: indentLevel, | ||||
| 		}) | ||||
| 
 | ||||
| 		token.value = indentLevel | ||||
| 		lexer.addToken(token) | ||||
| 	case '\n': | ||||
| 		// line break | ||||
| 
 | ||||
| @ -155,48 +161,49 @@ func (lexer *LexingOperation) tokenizeSymbolBeginning () (err error) { | ||||
| 			lexer.tokens = lexer.tokens[:tokenIndex] | ||||
| 		} | ||||
| 		 | ||||
| 		lexer.addToken (Token { | ||||
| 			kind: TokenKindNewline, | ||||
| 		}) | ||||
| 		token := lexer.newToken() | ||||
| 		token.kind = TokenKindNewline | ||||
| 		lexer.addToken(token) | ||||
| 		err = lexer.nextRune() | ||||
| 	case '"': | ||||
| 		err = lexer.tokenizeString(false) | ||||
| 	case '\'': | ||||
| 		err = lexer.tokenizeString(true) | ||||
| 	case ':': | ||||
| 		lexer.addToken (Token { | ||||
| 			kind: TokenKindColon, | ||||
| 		}) | ||||
| 		token := lexer.newToken() | ||||
| 		token.kind = TokenKindColon | ||||
| 		lexer.addToken(token) | ||||
| 		err = lexer.nextRune() | ||||
| 	case '.': | ||||
| 		lexer.addToken (Token { | ||||
| 			kind: TokenKindDot, | ||||
| 		}) | ||||
| 		token := lexer.newToken() | ||||
| 		token.kind = TokenKindDot | ||||
| 		lexer.addToken(token) | ||||
| 		err = lexer.nextRune() | ||||
| 	case '[': | ||||
| 		lexer.addToken (Token { | ||||
| 			kind: TokenKindLBracket, | ||||
| 		}) | ||||
| 		token := lexer.newToken() | ||||
| 		token.kind = TokenKindLBracket | ||||
| 		lexer.addToken(token) | ||||
| 		err = lexer.nextRune() | ||||
| 	case ']': | ||||
| 		lexer.addToken (Token { | ||||
| 			kind: TokenKindRBracket, | ||||
| 		}) | ||||
| 		token := lexer.newToken() | ||||
| 		token.kind = TokenKindRBracket | ||||
| 		lexer.addToken(token) | ||||
| 		err = lexer.nextRune() | ||||
| 	case '{': | ||||
| 		lexer.addToken (Token { | ||||
| 			kind: TokenKindLBrace, | ||||
| 		}) | ||||
| 		token := lexer.newToken() | ||||
| 		token.kind = TokenKindLBrace | ||||
| 		lexer.addToken(token) | ||||
| 		err = lexer.nextRune() | ||||
| 	case '}': | ||||
| 		lexer.addToken (Token { | ||||
| 			kind: TokenKindRBrace, | ||||
| 		}) | ||||
| 		token := lexer.newToken() | ||||
| 		token.kind = TokenKindRBrace | ||||
| 		lexer.addToken(token) | ||||
| 		err = lexer.nextRune() | ||||
| 	case '+': | ||||
| 		err = lexer.nextRune() | ||||
| 		if err != nil { return } | ||||
| 		token := Token { kind: TokenKindPlus } | ||||
| 		token := lexer.newToken() | ||||
| 		token.kind = TokenKindPlus | ||||
| 		if lexer.char == '+' { | ||||
| 			token.kind = TokenKindIncrement | ||||
| 		} | ||||
| @ -205,39 +212,40 @@ func (lexer *LexingOperation) tokenizeSymbolBeginning () (err error) { | ||||
| 	case '-': | ||||
| 		err = lexer.tokenizeDashBeginning() | ||||
| 	case '*': | ||||
| 		lexer.addToken (Token { | ||||
| 			kind: TokenKindAsterisk, | ||||
| 		}) | ||||
| 		token := lexer.newToken() | ||||
| 		token.kind = TokenKindAsterisk | ||||
| 		lexer.addToken(token) | ||||
| 		err = lexer.nextRune() | ||||
| 	case '/': | ||||
| 		lexer.addToken (Token { | ||||
| 			kind: TokenKindSlash, | ||||
| 		}) | ||||
| 		token := lexer.newToken() | ||||
| 		token.kind = TokenKindSlash | ||||
| 		lexer.addToken(token) | ||||
| 		err = lexer.nextRune() | ||||
| 	case '@': | ||||
| 		lexer.addToken (Token { | ||||
| 			kind: TokenKindAt, | ||||
| 		}) | ||||
| 		token := lexer.newToken() | ||||
| 		token.kind = TokenKindAt | ||||
| 		lexer.addToken(token) | ||||
| 		err = lexer.nextRune() | ||||
| 	case '!': | ||||
| 		lexer.addToken (Token { | ||||
| 			kind: TokenKindExclamation, | ||||
| 		}) | ||||
| 		token := lexer.newToken() | ||||
| 		token.kind = TokenKindExclamation | ||||
| 		lexer.addToken(token) | ||||
| 		err = lexer.nextRune() | ||||
| 	case '%': | ||||
| 		lexer.addToken (Token { | ||||
| 			kind: TokenKindPercent, | ||||
| 		}) | ||||
| 		token := lexer.newToken() | ||||
| 		token.kind = TokenKindPercent | ||||
| 		lexer.addToken(token) | ||||
| 		err = lexer.nextRune() | ||||
| 	case '~': | ||||
| 		lexer.addToken (Token { | ||||
| 			kind: TokenKindTilde, | ||||
| 		}) | ||||
| 		token := lexer.newToken() | ||||
| 		token.kind = TokenKindTilde | ||||
| 		lexer.addToken(token) | ||||
| 		err = lexer.nextRune() | ||||
| 	case '<': | ||||
| 		err = lexer.nextRune() | ||||
| 		if err != nil { return } | ||||
| 		token := Token { kind: TokenKindLessThan } | ||||
| 		token := lexer.newToken() | ||||
| 		token.kind = TokenKindLessThan | ||||
| 		if lexer.char == '<' { | ||||
| 			token.kind = TokenKindLShift | ||||
| 		} | ||||
| @ -246,7 +254,8 @@ func (lexer *LexingOperation) tokenizeSymbolBeginning () (err error) { | ||||
| 	case '>': | ||||
| 		err = lexer.nextRune() | ||||
| 		if err != nil { return } | ||||
| 		token := Token { kind: TokenKindGreaterThan } | ||||
| 		token := lexer.newToken() | ||||
| 		token.kind = TokenKindGreaterThan | ||||
| 		if lexer.char == '>' { | ||||
| 			token.kind = TokenKindRShift | ||||
| 		} | ||||
| @ -255,7 +264,8 @@ func (lexer *LexingOperation) tokenizeSymbolBeginning () (err error) { | ||||
| 	case '|': | ||||
| 		err = lexer.nextRune() | ||||
| 		if err != nil { return } | ||||
| 		token := Token { kind: TokenKindBinaryOr } | ||||
| 		token := lexer.newToken() | ||||
| 		token.kind = TokenKindBinaryOr | ||||
| 		if lexer.char == '|' { | ||||
| 			token.kind = TokenKindLogicalOr | ||||
| 		} | ||||
| @ -264,7 +274,8 @@ func (lexer *LexingOperation) tokenizeSymbolBeginning () (err error) { | ||||
| 	case '&': | ||||
| 		err = lexer.nextRune() | ||||
| 		if err != nil { return } | ||||
| 		token := Token { kind: TokenKindBinaryAnd } | ||||
| 		token := lexer.newToken() | ||||
| 		token.kind = TokenKindBinaryAnd | ||||
| 		if lexer.char == '&' { | ||||
| 			token.kind = TokenKindLogicalAnd | ||||
| 		} | ||||
| @ -272,7 +283,7 @@ func (lexer *LexingOperation) tokenizeSymbolBeginning () (err error) { | ||||
| 		err = lexer.nextRune() | ||||
| 	default: | ||||
| 		err = file.NewError ( | ||||
| 			lexer.file.Location(), | ||||
| 			lexer.file.Location(1), | ||||
| 			"unexpected symbol character " + | ||||
| 			string(lexer.char), | ||||
| 			file.ErrorKindError) | ||||
| @ -287,7 +298,8 @@ func (lexer *LexingOperation) tokenizeDashBeginning () (err error) { | ||||
| 	if err != nil { return } | ||||
| 
 | ||||
| 	if lexer.char == '-' { | ||||
| 		token := Token { kind: TokenKindDecrement } | ||||
| 		token := lexer.newToken() | ||||
| 		token.kind = TokenKindDecrement | ||||
| 
 | ||||
| 		err = lexer.nextRune() | ||||
| 		if err != nil { return } | ||||
| @ -298,7 +310,8 @@ func (lexer *LexingOperation) tokenizeDashBeginning () (err error) { | ||||
| 		} | ||||
| 		lexer.addToken(token) | ||||
| 	} else if lexer.char == '>' { | ||||
| 		token := Token { kind: TokenKindReturnDirection } | ||||
| 		token := lexer.newToken() | ||||
| 		token.kind = TokenKindReturnDirection | ||||
| 
 | ||||
| 		err = lexer.nextRune()  | ||||
| 		if err != nil { return } | ||||
| @ -307,13 +320,19 @@ func (lexer *LexingOperation) tokenizeDashBeginning () (err error) { | ||||
| 	} else if lexer.char >= '0' && lexer.char <= '9' { | ||||
| 		lexer.tokenizeNumberBeginning(true) | ||||
| 	} else { | ||||
| 		token := Token { kind: TokenKindMinus } | ||||
| 		token := lexer.newToken() | ||||
| 		token.kind = TokenKindMinus | ||||
| 		lexer.addToken(token) | ||||
| 	} | ||||
| 	 | ||||
| 	return | ||||
| } | ||||
| 
 | ||||
| // newToken creates a new token from the lexer's current position in the file. | ||||
| func (lexer *LexingOperation) newToken () (token Token) { | ||||
| 	return Token { location: lexer.file.Location(1) } | ||||
| } | ||||
| 
 | ||||
| // addToken adds a new token to the lexer's token slice. | ||||
| func (lexer *LexingOperation) addToken (token Token) { | ||||
| 	lexer.tokens = append(lexer.tokens, token) | ||||
| @ -334,7 +353,7 @@ func (lexer *LexingOperation) nextRune () (err error) { | ||||
| 	lexer.char, _, err = lexer.file.ReadRune() | ||||
| 	if err != nil && err != io.EOF { | ||||
| 		return file.NewError ( | ||||
| 			lexer.file.Location(), | ||||
| 			lexer.file.Location(1), | ||||
| 			err.Error(), file.ErrorKindError) | ||||
| 	} | ||||
| 	return | ||||
|  | ||||
| @ -8,6 +8,8 @@ func (lexer *LexingOperation) tokenizeNumberBeginning (negative bool) (err error | ||||
| 	var fragment float64 | ||||
| 	var isFloat  bool | ||||
| 
 | ||||
| 	token := lexer.newToken() | ||||
| 
 | ||||
| 	if lexer.char == '0' { | ||||
| 		lexer.nextRune() | ||||
| 
 | ||||
| @ -23,7 +25,7 @@ func (lexer *LexingOperation) tokenizeNumberBeginning (negative bool) (err error | ||||
| 			number, fragment, isFloat, err = lexer.tokenizeNumber(8) | ||||
| 		} else { | ||||
| 			return file.NewError ( | ||||
| 				lexer.file.Location(), | ||||
| 				lexer.file.Location(1), | ||||
| 				"unexpected character in number literal", | ||||
| 				file.ErrorKindError) | ||||
| 		} | ||||
| @ -33,8 +35,6 @@ func (lexer *LexingOperation) tokenizeNumberBeginning (negative bool) (err error | ||||
| 
 | ||||
| 	if err != nil { return } | ||||
| 
 | ||||
| 	token := Token { } | ||||
| 
 | ||||
| 	if isFloat { | ||||
| 		floatNumber := float64(number) + fragment | ||||
| 	 | ||||
|  | ||||
| @ -8,6 +8,8 @@ func (lexer *LexingOperation) tokenizeString (isRuneLiteral bool) (err error) { | ||||
| 	err = lexer.nextRune() | ||||
| 	if err != nil { return } | ||||
| 
 | ||||
| 	token := lexer.newToken() | ||||
| 
 | ||||
| 	got := "" | ||||
| 
 | ||||
| 	for { | ||||
| @ -38,12 +40,10 @@ func (lexer *LexingOperation) tokenizeString (isRuneLiteral bool) (err error) { | ||||
| 	err = lexer.nextRune() | ||||
| 	if err != nil { return } | ||||
| 
 | ||||
| 	token := Token { } | ||||
| 
 | ||||
| 	if isRuneLiteral { | ||||
| 		if len(got) > 1 { | ||||
| 			err = file.NewError ( | ||||
| 				lexer.file.Location(), | ||||
| 				lexer.file.Location(1), | ||||
| 				"excess data in rune literal", | ||||
| 				file.ErrorKindError) | ||||
| 			return | ||||
| @ -99,7 +99,7 @@ func (lexer *LexingOperation) getEscapeSequence () (result rune, err error) { | ||||
|                  | ||||
|                 if len(number) < 3 { | ||||
| 			err = file.NewError ( | ||||
| 				lexer.file.Location(), | ||||
| 				lexer.file.Location(1), | ||||
| 				"octal escape sequence too short", | ||||
| 				file.ErrorKindError) | ||||
| 			return | ||||
| @ -133,7 +133,7 @@ func (lexer *LexingOperation) getEscapeSequence () (result rune, err error) { | ||||
|                  | ||||
|                 if len(number) < want { | ||||
| 			err = file.NewError ( | ||||
| 				lexer.file.Location(), | ||||
| 				lexer.file.Location(1), | ||||
| 				"hex escape sequence too short ", | ||||
| 				file.ErrorKindError) | ||||
| 			return | ||||
| @ -143,7 +143,7 @@ func (lexer *LexingOperation) getEscapeSequence () (result rune, err error) { | ||||
|                 result = rune(parsedNumber) | ||||
| 	} else { | ||||
| 		err = file.NewError ( | ||||
| 			lexer.file.Location(), | ||||
| 			lexer.file.Location(1), | ||||
| 			"unknown escape character " + | ||||
| 			string(lexer.char), file.ErrorKindError) | ||||
| 		return | ||||
|  | ||||
| @ -78,7 +78,7 @@ func (token Token) Value () (value any) { | ||||
| 
 | ||||
| // Equals returns whether this token is equal to another token | ||||
| func (token Token) Equals (testToken Token) (match bool) { | ||||
| 	return token == testToken | ||||
| 	return token.value == testToken.value && token.Is(testToken.kind) | ||||
| }  | ||||
| 
 | ||||
| // Location returns the location of the token in its file. | ||||
|  | ||||
		Reference in New Issue
	
	Block a user