|
@@ -46,121 +46,6 @@ exports.emitEndStatement = function(context){
|
|
|
context.codeGenerator().write(";\n");
|
|
|
};
|
|
|
|
|
|
-exports.Case = ChainedContext.extend({
|
|
|
- init: function CaseContext(context){
|
|
|
- ChainedContext.prototype.init.call(this, context);
|
|
|
- this.__type = undefined;
|
|
|
- this.__firstCase = true;
|
|
|
- this.__var = this.root().currentScope().generateTempVar("case");
|
|
|
- this.codeGenerator().write("var " + this.__var + " = ");
|
|
|
- },
|
|
|
- caseVar: function(){return this.__var;},
|
|
|
- handleExpression: function(e){
|
|
|
- var type = e.type();
|
|
|
- var gen = this.codeGenerator();
|
|
|
- if (type instanceof Type.String){
|
|
|
- var v;
|
|
|
- if (Type.stringAsChar(type, {set: function(value){v = value;}})){
|
|
|
- gen.write(v);
|
|
|
- type = basicTypes.ch;
|
|
|
- }
|
|
|
- }
|
|
|
- if (!Type.isInt(type) && type != basicTypes.ch)
|
|
|
- throw new Errors.Error(
|
|
|
- Type.intsDescription() + " or 'CHAR' expected as CASE expression");
|
|
|
- this.__type = type;
|
|
|
- gen.write(";\n");
|
|
|
- },
|
|
|
- beginCase: function(){
|
|
|
- if (this.__firstCase)
|
|
|
- this.__firstCase = false;
|
|
|
- else
|
|
|
- this.codeGenerator().write("else ");
|
|
|
- },
|
|
|
- handleLabelType: function(type){
|
|
|
- if (!Cast.areTypesMatch(type, this.__type))
|
|
|
- throw new Errors.Error(
|
|
|
- "label must be '" + Type.typeName(this.__type) + "' (the same as case expression), got '"
|
|
|
- + Type.typeName(type) + "'");
|
|
|
- }
|
|
|
-});
|
|
|
-
|
|
|
-exports.CaseLabelList = ChainedContext.extend({
|
|
|
- init: function CaseLabelListContext(context){
|
|
|
- ChainedContext.prototype.init.call(this, context);
|
|
|
- this.__glue = "";
|
|
|
- },
|
|
|
- handleLabelType: function(type){this.parent().handleLabelType(type);},
|
|
|
- handleRange: function(from, to){
|
|
|
- var parent = this.parent();
|
|
|
- if (!this.__glue)
|
|
|
- parent.caseLabelBegin();
|
|
|
-
|
|
|
- var v = parent.parent().caseVar();
|
|
|
- var cond = to === undefined
|
|
|
- ? v + " === " + from.value
|
|
|
- : "(" + v + " >= " + from.value + " && " + v + " <= " + to.value + ")";
|
|
|
- this.codeGenerator().write(this.__glue + cond);
|
|
|
- this.__glue = " || ";
|
|
|
- },
|
|
|
- endParse: function(){this.parent().caseLabelEnd();}
|
|
|
-});
|
|
|
-
|
|
|
-exports.CaseLabel = ChainedContext.extend({
|
|
|
- init: function CaseLabelContext(context){
|
|
|
- ChainedContext.prototype.init.call(this, context);
|
|
|
- },
|
|
|
- caseLabelBegin: function(){
|
|
|
- this.parent().beginCase();
|
|
|
- this.codeGenerator().write("if (");
|
|
|
- },
|
|
|
- caseLabelEnd: function(){
|
|
|
- var gen = this.codeGenerator();
|
|
|
- gen.write(")");
|
|
|
- gen.openScope();
|
|
|
- },
|
|
|
- handleLabelType: function(type){this.parent().handleLabelType(type);},
|
|
|
- handleRange: function(from, to){this.parent().handleRange(from, to);},
|
|
|
- endParse: function(){this.codeGenerator().closeScope("");}
|
|
|
-});
|
|
|
-
|
|
|
-exports.CaseRange = ChainedContext.extend({
|
|
|
- init: function CaseRangeContext(context){
|
|
|
- ChainedContext.prototype.init.call(this, context);
|
|
|
- this.__from = undefined;
|
|
|
- this.__to = undefined;
|
|
|
- },
|
|
|
- codeGenerator: function(){return nullCodeGenerator;}, // suppress any output
|
|
|
- handleLabel: function(type, v){
|
|
|
- this.parent().handleLabelType(type);
|
|
|
- if (this.__from === undefined )
|
|
|
- this.__from = v;
|
|
|
- else
|
|
|
- this.__to = v;
|
|
|
- },
|
|
|
- handleConst: function(type, value){
|
|
|
- if (type instanceof Type.String){
|
|
|
- if (!Type.stringAsChar(type, {set: function(v){value = v;}}))
|
|
|
- throw new Errors.Error("single-character string expected");
|
|
|
- type = basicTypes.ch;
|
|
|
- value = new ConstValue.Int(value);
|
|
|
- }
|
|
|
- this.handleLabel(type, value);
|
|
|
- },
|
|
|
- handleIdent: function(id){
|
|
|
- var s = ContextHierarchy.getSymbol(this.root(), id);
|
|
|
- if (!s.isConst())
|
|
|
- throw new Errors.Error("'" + id + "' is not a constant");
|
|
|
-
|
|
|
- var type = s.info().type;
|
|
|
- if (type instanceof Type.String)
|
|
|
- this.handleConst(type, undefined);
|
|
|
- else
|
|
|
- this.handleLabel(type, s.info().value);
|
|
|
- },
|
|
|
- endParse: function(){this.parent().handleRange(this.__from, this.__to);}
|
|
|
-});
|
|
|
-
|
|
|
exports.While = ChainedContext.extend({
|
|
|
init: function WhileContext(context){
|
|
|
ChainedContext.prototype.init.call(this, context);
|