scope.js 2.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081
  1. "use strict";
  2. var Class = require("rtl.js").Class;
  3. var Errors = require("errors.js");
  4. var Procedure = require("procedure.js");
  5. var Symbol = require("symbol.js");
  6. var Type = require("type.js");
  7. var stdSymbols = function(){
  8. var symbols = {};
  9. for(var t in Type.basic){
  10. var type = Type.basic[t];
  11. symbols[type.name()] = new Symbol.Symbol(type.name(), new Type.TypeId(type));
  12. }
  13. symbols["LONGREAL"] = new Symbol.Symbol("LONGREAL", new Type.TypeId(Type.basic.real));
  14. var predefined = Procedure.predefined;
  15. for(var i = 0; i < predefined.length; ++i){
  16. var s = predefined[i];
  17. symbols[s.id()] = s;
  18. }
  19. return symbols;
  20. }();
  21. var Scope = Class.extend({
  22. init: function Scope(id){
  23. this.__id = id;
  24. this.__symbols = {};
  25. for(var p in stdSymbols)
  26. this.__symbols[p] = stdSymbols[p];
  27. this.__unresolved = [];
  28. },
  29. id: function(){return this.__id;},
  30. addSymbol: function(symbol){
  31. var id = symbol.id();
  32. if (this.findSymbol(id))
  33. throw new Errors.Error( "'" + id + "' already declared");
  34. this.__symbols[id] = symbol;
  35. var i = this.__unresolved.indexOf(id);
  36. if (i != -1){
  37. var info = symbol.info();
  38. if (!(info.type() instanceof Type.Record))
  39. throw new Errors.Error(
  40. "'" + id + "' must be of RECORD type because it was used before in the declation of POINTER");
  41. this.__unresolved.splice(i, 1);
  42. }
  43. },
  44. findSymbol: function(ident){return this.__symbols[ident];},
  45. addUnresolved: function(id){this.__unresolved.push(id);},
  46. unresolved: function(){return this.__unresolved;}
  47. });
  48. var ProcedureScope = Scope.extend({
  49. init: function ProcedureScope(){
  50. Scope.prototype.init.call(this, "procedure");
  51. },
  52. addSymbol: function(symbol, exported){
  53. if (exported)
  54. throw new Errors.Error("cannot export from within procedure: "
  55. + symbol.info().idType() + " '" + symbol.id() + "'");
  56. Scope.prototype.addSymbol.call(this, symbol, exported);
  57. }
  58. });
  59. var Module = Scope.extend({
  60. init: function Module(){
  61. Scope.prototype.init.call(this, "module");
  62. this.__exports = [];
  63. },
  64. addSymbol: function(symbol, exported){
  65. if (exported)
  66. if (!symbol.isType() || symbol.info().type() instanceof Type.Record)
  67. this.__exports.push(symbol);
  68. Scope.prototype.addSymbol.call(this, symbol, exported);
  69. },
  70. exports: function(){return this.__exports;}
  71. });
  72. exports.Procedure = ProcedureScope;
  73. exports.Module = Module;