1 /*
     
2 
     3 This script interprets the results of a bad parse into something readable so
     
4 that a game author can fix their Hootscript.
     
5 
     6 TODO: more common errors in plain English
     
7 
     8 */
     
9 
    10 
    11 function getErrorMessage(parseResults, origScript){
    
12 	// parseresults contains:
    
13 	// "script":script, "stack":stack, "atom":atom.name}
    
14 
    15 	var contextsize = 10; // characters around the error to show
    
16 	var errorsize = 20; // characters of actual error to show
    
17 
    18 	var script = parseResults.script;
    
19 	var pos = origScript.length - script.length;
    
20 	var beforescript = origScript.slice(0,pos)
    
21 	var linecount = beforescript.split("\n").length;
    
22 
    23 	var eos = false;
    
24 
    25 	if(pos == origScript.length){
    
26 		script = "* the end of the script *";
    
27 		eos = true;
    
28 	}
    
29 	else{
    
30 
    31 		// format the snippet of script that will appear before the error
    
32 		if(beforescript.length > contextsize){
    
33 			beforescript = "..."+beforescript.slice(beforescript.length-10);
    
34 		}
    
35 
    36 		// from our error script, grab the error up until the first bit of whitespace
    
37 		var errorbit = /(\S)+/.exec(script);
    
38 		errorbit = errorbit[0];
    
39 		if(errorbit.length>errorsize){
    
40 			errorbit = errorbit.slice(0,errorsize);
    
41 		}
    
42 
    43 		// and then grab some script after the error
    
44 		var afterscript = script.slice(errorbit.length);
    
45 		if(afterscript.length > contextsize){
    
46 			afterscript = afterscript.slice(0,contextsize)+"...";
    
47 		}
    
48 
    49 		// and then smash it all into a pretty little formatted HTML snippet
    
50 		script = "<i>"+beforescript+"</i>"+errorbit+"<i>"+afterscript+"</i>";
    
51 		script = script.replace(/\n/g,"<i>↵</i>");
    
52 		script = script.replace(/\s+/g," ");
    
53 	}
    
54 
    55 
    56 
    57 
    58 	// now come up with some specific errors
    
59 	switch(parseResults.atom){
    
60 		case "script":
    
61 			error = "Ran into <u>"+script+"</u> while looking for a thing.  To define a thing, be sure to use the format <b>[thing name]:</b>. Don't forget that every game needs to have a [start]: thing to begin the story!";
    
62 			break;
    
63 		case "colon":
    
64 			error = "I was looking for a ':' (colon) after what appeared to be the name of a thing and found <u>"+script+"</u> instead.  Perhaps you're missing the ':' after a thing name?  Things should be defined using this format: <b>[thing name]</b>'";
    
65 			break;
    
66 
    67 		case "name":
    
68 			error = "Did not understand <u>"+script+"</u>.  It looks like this should be the name of a thing?  Names should always be fully surrounded with brackets like <b>[this]</b>. They must also not contain square brackets or underscores ([,],_) as part of the name.";
    
69 			break;
    
70 
    71 		case "qclose":
    
72 			error = "I ran into <u>"+script+"</u> while looking for the closing slash in some display text.  Be sure that you have both a start and end slash <b>/like this/</b>. Hint: the problem is probably in the last display text in the script.";
    
73 			break;
    
74 
    75 		case "func": case "expr":
    
76 			if(eos){
    
77 				error = "I ran out of Hootscript while looking for a statement or expression.  In other words, it looks like you either have a thing that is empty (contains no commands or display text) or you might have an if or else statement followed by nothing.  Please give me something to do here!"
    
78 				break;
    
79 			}
    
80 
    81 			error = "I tried to interpret this and failed: <u>"+script+"</u>.<br><br>If this was a command of some sort, please check the documentation for the correct spelling of this command.<br><br>Also, things cannot be empty, so maybe you're trying to define a new thing here after an empty thing?<br><br>Or perhaps this was text that you'd written to be displayed? If that's the case, you probably have a missing slash at the end of your display text.  All display text should begin and end with slashes <b>/like this/</b>.  Hint: the problem is probably the display text that comes just before this one in your script!";
    
82 			break;
    
83 
    84 		case "to":
    
85 			error = "I ran into <u>"+script+"</u> while looking for the 'to' in a set statement like this: <b>set [some variable] to ...</b>";
    
86 			break;
    
87 
    88 		case "num":
    
89 			error = "I ran into <u>"+script+"</u> while looking for a number. This is probably after a 'to' in a set statement like this: <b>set [some variable] to 50</b> where 50 is the number you're trying to set.";
    
90 			break;
    
91 
    92 		case "strname":
    
93 			error = "I was looking at what appeared to be the name of a thing or variable <u>"+script+"</u> within some display text.  It looks like perhaps you left the closing square bracket off of the end of the name?  Calling things or variables within display text should look something like this: <b>/The item is [item]./</b>";
    
94 			break;
    
95 
    96 		case "link":
    
97 			error = "I was looking at what appeared to be a link to a thing <u>"+script+"</u> within some display text.  It looks like perhaps you left the closing underscore off of the end of the link name?  Linking to things within display text should look something like this: <b>/Here is _a thing_ linked in display text./</b>";
    
98 			break;
    
99 
   100 		case "value":
   
101 			error = "I was looking for a variable name or number in an if statement.  Instead I encountered <u>"+script+"</u>.  If statements should take the general form of <b>if <span style=\"font-style:italic;\">value test value2</span> then ...</b> where <span style=\"font-style:italic;\">value</span> and <span style=\"font-style:italic;\">value2</span> are either numbers <b>54</b> or variables <b>[variable]</b> and <span style=\"font-style:italic;\">test</span> is <b>equals</b> or <b>doesn't equal</b> or <b>less than</b> or <b>greater than</b>.  Please see the documentation for some more examples.";
   
102 			break;
   
103 
   104 		case "test": case "eq": case "gt": case "de":
   
105 			error = "I was looking for a test in an if statement. Instead I encountered <u>"+script+"</u>.  If statements should take the general form of <b>if <span style=\"font-style:italic;\">value test value2</span> then ...</b> where <span style=\"font-style:italic;\">value</span> and <span style=\"font-style:italic;\">value2</span> are either numbers <b>54</b> or variables <b>[variable]</b> and <span style=\"font-style:italic;\">test</span> is <b>equals</b> or <b>doesn't equal</b> or <b>less than</b> or <b>greater than</b>.  Please see the documentation for some more examples.";
   
106 			break;
   
107 
   108 		case "end":
   
109 			error = "I was looking for <b>end</b> to complete an if statement but instead I encountered <u>"+script+"</u>.  Maybe one of your if or else statements does not have a matching end.<br><br>On the other hand, if this was supposed to be a real command inside of an if or else, then it might be wrong. Check the documentation for the correct spelling and format of Hootscript commands.";
   
110 			break;
   
111 
   112 		case "then":
   
113 			error = "I was looking for a <b>then</b> to complete the test portion of an if statement, but instead I encountered <u>"+script+"</u>. If statements should take the general form of <b>if <span style=\"font-style:italic;\">test</span> then ...";
   
114 			break;
   
115 
   116 
   117 		default: 
   
118 			error = "Encountered <u>"+script+"</u> while looking for <b>"+parseResults.atom+"</b>.  Sorry I can't be less cryptic.  Please take a look at the text carefully and refer to the documentation for the correct way to do what you're trying to do.";
   
119 	}
   
120 
   121 
   122 	return "<p>Line "+linecount+": "+error+"</p>";
   
123 }
   
124