Ver Fonte

Added basic syntax highlighting for GLSL

Ivan Safrin há 12 anos atrás
pai
commit
8275c69b9c

+ 7 - 1
IDE/Contents/Include/PolycodeTextEditor.h

@@ -69,9 +69,15 @@ class PolycodeSyntaxHighlighter : public UITextInputSyntaxHighlighter {
 			
 		std::vector<SyntaxHighlightToken> parseText(String text);		
 		std::vector<SyntaxHighlightToken> parseLua(String text);	
-		
+		std::vector<SyntaxHighlightToken> parseGLSL(String text);
+			
+		static const int MODE_LUA = 0;
+		static const int MODE_GLSL = 1;
+						
 	protected:
 	
+		int mode;
+	
 		std::vector<char> separators;
 		std::vector<String> keywords;		
 };

+ 164 - 9
IDE/Contents/Source/PolycodeTextEditor.cpp

@@ -96,17 +96,33 @@ void SyntaxHighlightTheme::loadFromFile(String themeName) {
 
 PolycodeSyntaxHighlighter::PolycodeSyntaxHighlighter(String extension) {
 	
-//	String separators = " ;()\t\n=+-/\\'\"";	
-//	String keywords = "true,false,";
+
+	if(extension == "lua") {
+		mode = MODE_LUA;
+
+		std::vector<String>separators_s = String("[ * [ ] { } ; . , : # ( ) \t \n = + - / \\ ' \"").split(" ");
+		separators_s.push_back(" ");
 	
-	std::vector<String>separators_s = String("[ * [ ] { } ; . , : # ( ) \t \n = + - / \\ ' \"").split(" ");
-	separators_s.push_back(" ");
+		for(int i=0; i < separators_s.size(); i++) {
+			separators.push_back(separators_s[i][0]);
+		}
 	
-	for(int i=0; i < separators_s.size(); i++) {
-		separators.push_back(separators_s[i][0]);
+		keywords = String("for cast safe_cast and require true false class self break do end else elseif function if local nil not or repeat return then until while").split(" ");
+		
+	} else if(extension == "vert" || extension == "frag") {
+		mode = MODE_GLSL;
+		
+		std::vector<String>separators_s = String("[ * [ ] { } ; . , : ( ) \t \n = + - / \\ ' \"").split(" ");
+		separators_s.push_back(" ");
+	
+		for(int i=0; i < separators_s.size(); i++) {
+			separators.push_back(separators_s[i][0]);
+		}
+	
+		keywords = String("for cast and true falsebreak do end else if notreturn then until while uniform varying sampler2D sampler3D vec2 vec3 vec4 float in inout void mat2 mat3 mat4 bool int #define #ifdef #elif #else #endif").split(" ");
+		
 	}
 	
-	keywords = String("for cast safe_cast and require true false class self break do end else elseif function if local nil not or repeat return then until while").split(" ");
 }
 
 PolycodeSyntaxHighlighter::~PolycodeSyntaxHighlighter() {
@@ -130,7 +146,146 @@ bool PolycodeSyntaxHighlighter::contains_char(char part, std::vector<char> *list
 }
 
 std::vector<SyntaxHighlightToken> PolycodeSyntaxHighlighter::parseText(String text) {
-	return parseLua(text);
+	if(mode == MODE_LUA) {	
+		return parseLua(text);
+	} else {
+		return parseGLSL(text);	
+	}
+}
+
+	
+std::vector<SyntaxHighlightToken> PolycodeSyntaxHighlighter::parseGLSL(String text) {
+	std::vector<SyntaxHighlightToken> tokens;
+	
+	text = text+"\n";
+	
+	const int MODE_GENERAL = 0;
+	const int MODE_COMMENT = 1;
+	const int MODE_STRING = 2;
+	const int MODE_METHOD = 3;
+	const int MODE_KEYWORD = 4;
+	const int MODE_NUMBER = 5;
+	const int MODE_MEMBER = 6;
+						
+	int mode = MODE_GENERAL;
+	
+	bool isComment = false;
+	
+	String line = "";
+	
+	char lastSeparator = ' ';
+
+	
+	for(int i=0; i < text.length(); i++) {
+		char ch = text[i];				
+		if(contains_char(ch, &separators)) {			
+
+			unsigned int type = mode;
+			unsigned int ch_type = mode;
+
+	
+			if(ch == '\"' && mode != MODE_COMMENT)
+				ch_type = MODE_STRING;
+	
+			if(mode != MODE_STRING && ch == '('  && mode != MODE_COMMENT) {
+				type = MODE_METHOD;
+			}
+
+			if(mode != MODE_STRING  && mode != MODE_COMMENT) {
+				if(contains(line, &keywords)) {
+					type = MODE_KEYWORD;
+				}
+			}
+	
+			if(mode != MODE_STRING && !isComment && mode != MODE_COMMENT) {
+			
+				if(line.isNumber()) {
+					type = MODE_NUMBER;
+				} else {
+					if(lastSeparator == '.' && ch != '.' && ch != ':') {
+						type = MODE_MEMBER;
+					}							
+				}
+			}		
+	
+			if(isComment) {
+				type = MODE_COMMENT;
+				ch_type = MODE_COMMENT;
+			}
+				
+			if(mode == MODE_COMMENT) {
+				type = MODE_COMMENT;
+				ch_type = MODE_COMMENT;
+			}
+			
+	
+			if(line != "")
+				tokens.push_back(SyntaxHighlightToken(line, type));
+			tokens.push_back(SyntaxHighlightToken(ch, ch_type));
+
+			if(ch == '/' && lastSeparator == '/' && mode != MODE_STRING) {
+				isComment = true;
+				tokens[tokens.size()-1].type = MODE_COMMENT;
+				tokens[tokens.size()-2].type = MODE_COMMENT;				
+			}
+
+			if(ch == '*' && lastSeparator == '/' && mode != MODE_STRING) {
+				unsigned int old_mode = mode;
+				tokens[tokens.size()-1].type = MODE_COMMENT;
+				tokens[tokens.size()-2].type = MODE_COMMENT;				
+				mode = MODE_COMMENT;				
+			}
+			
+			if(ch == '/' && lastSeparator == '*' && mode == MODE_COMMENT) {
+				mode = MODE_GENERAL;
+			}
+			
+			if(ch == '\n' )
+				isComment = false;
+				
+
+			if(ch == '\"'  && mode != MODE_COMMENT) {
+				if(mode == MODE_STRING) {
+					mode = MODE_GENERAL;	
+				} else {
+					mode = MODE_STRING;
+				}
+			}	
+						
+			line = "";
+			lastSeparator = ch;			
+		} else {
+			line.append(ch);
+		}
+	}
+	
+	for(int i=0; i < tokens.size(); i++) {
+		switch(tokens[i].type) {
+			case MODE_STRING:
+				tokens[i].color = globalSyntaxTheme->colors[4];			
+			break;
+			case MODE_COMMENT:
+				tokens[i].color = globalSyntaxTheme->colors[1];			
+			break;			
+			case MODE_METHOD:
+				tokens[i].color = globalSyntaxTheme->colors[3];			
+			break;			
+			case MODE_KEYWORD:
+				tokens[i].color = globalSyntaxTheme->colors[2];
+			break;		
+			case MODE_NUMBER:
+				tokens[i].color = globalSyntaxTheme->colors[6];
+			break;		
+			case MODE_MEMBER:
+				tokens[i].color = globalSyntaxTheme->colors[5];
+			break;															
+			default:
+				tokens[i].color = globalSyntaxTheme->colors[0];
+			break;
+		}
+	}
+	
+	return tokens;
 }
 	
 std::vector<SyntaxHighlightToken> PolycodeSyntaxHighlighter::parseLua(String text) {
@@ -313,7 +468,7 @@ bool PolycodeTextEditor::openFile(OSFileEntry filePath) {
 		
 	syntaxHighligher = NULL;
 	
-	if(filePath.extension == "lua") {
+	if(filePath.extension == "lua" || filePath.extension == "vert" || filePath.extension == "frag") {
 		syntaxHighligher = new PolycodeSyntaxHighlighter(filePath.extension);
 		textInput->setSyntaxHighlighter(syntaxHighligher);
 	} else {