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