Please log in to view the forum threads.

Be warned, NEVER give your account details to anyone!
Double accounts are unwanted and strictly prohibited!




If your account got hacked please immediately report this to the following Discord id's: Pr0Master#7146 or Snake#0582

You can join our DISCORD support group by using the following link: https://discordapp.com/invite/fgbMxZG


Your Infinity Team

    Scripting language

    Share
    avatar
    Starkkz
    Developer
    Developer

    Posts : 55
    Points : 75
    Likes : 6
    Age : 20
    Country : Chile/Santiago
    Join date : 2013-05-04

    Scripting language

    Post by Starkkz on Thu Feb 27, 2014 10:30 pm

    Probably it's not the right section since it's on the CS2D cathegory, but I have to post my script somewhere.

    I've been trying to make a scripting language in Lua but it's kinda hard since I can't get to run some operators before OTHER operators.
    I can't do a = 10 + 3 because the "=" operator is executed before the "+" operator, and so a results 10.
    I'll keep doing some research on this, but I will put my script here. It's not ready to run other scripts but at least it parses them properly and checks for errors.

    Code:

    ScriptBase = {}
    StateBase = {
      Operators = {
        ["^"] = {function (Script, A, B) return A.Value ^ B.Value end, 5},
        ["*"] = {function (Script, A, B) return A.Value * B.Value end, 4},
        ["/"] = {function (Script, A, B) return A.Value / B.Value end, 3},
        ["+"] = {function (Script, A, B) return A.Value + B.Value end, 2},
        ["-"] = {function (Script, A, B) return A.Value - B.Value end, 1},
        ["="] = {function (Script, A, B) Script:Set(A.Name, B.Value) end, 0},
      },
    }

    ScriptMetatable = {__index = ScriptBase}
    StateMetatable = {__index = StateBase}

    function RunTasks(Tasks)
      for TaskID, Task in pairs(Tasks) do
        if type(Task) == "function" then
          Task()
        elseif type(Task) == "table" then
          if #Task > 0 then
            RunTasks(Task)
          else
            Tasks[TaskID] = nil
          end
        end
      end
    end

    function ScriptMetatable:__call()
      RunTasks(self.Tasks)
    end

    function ScriptBase:Error(Error, Line, Position, Source)
      local Error = Error or self.Error
      local Line = Line or self.Line
      local Position = Position or self.LinePosition
      local Source = Source or self.Source
      if Source then
        return error(Source..": on line "..Line..", position "..Position..": "..Error)
      end
      return error("on line "..Line..", position "..Position..": "..Error)
    end

    function ScriptBase:Set(Key, Value)
      if self.Env[Key] then
        self.Env[Key] = Value
      elseif self.SourceScript then
        self.SourceScript:Set(Key, Value)
      elseif self.State then
        self.State[Key] = Value
      end
    end

    function ScriptBase:Get(Key)
      if self.Env[Key] then
        return self.Env[Key]
      elseif self.SourceScript then
        return self.SourceScript:Get(Key)
      elseif self.State then
        return self.State[Key]
      end
    end

    function ScriptBase:ReadCharacter()
      local Character = string.sub(self.String, self.Position, self.Position)
      if Character == "\n" then
        self.Line = self.Line + 1
        self.LinePosition = 1
        self.Position = self.Position + 1
        return self:ReadCharacter()
      elseif Character:len() == 0 then
        return nil
      end
      return Character
    end

    function ScriptBase:NextCharacter()
      self.LinePosition = self.LinePosition + 1
      self.Position = self.Position + 1
    end

    function StateBase:LoadString(String, Source, SourceScript)
      local Script = {
        String = String,
        State = self,
        Line = 1,
        LinePosition = 1,
        Position = 1,
        Source = Source,
        SourceScript = SourceScript,
       
        Env = {},
        Stack = {},
        Tasks = {},
      }
      setmetatable(Script, ScriptMetatable)
     
      local Brackets = {}
      local BracketType = {}
      local BracketEnd = {}
      local BracketLine = {}
      local BracketLinePosition = {}
     
      local ValueTable = {}
      local TaskTable = {}
      local OperatorTable = {}
      local Key = ""
     
      while true do
        local Char = Script:ReadCharacter()
        if not Char then
          local BracketID = #Brackets
          if BracketID > 0 then
            local BracketPosition = Brackets[BracketID]
            local Type = BracketType[BracketPosition]
            local Line = BracketLine[BracketPosition]
            local LinePosition = BracketLinePosition[BracketPosition]
            return Script:Error("unterminated bracket '"..Type.."'", Line, LinePosition)
          end
          break
        elseif Char == "{" or Char == "(" or Char == "[" then
          table.insert(Brackets, Script.Position)
          BracketType[Script.Position] = Char
          BracketLine[Script.Position] = Script.Line
          BracketLinePosition[Script.Position] = Script.LinePosition
          Script:NextCharacter()
        elseif Char == "}" then
          local BracketID = #Brackets
          if BracketID > 0 then
            local BracketPosition = Brackets[BracketID]
            if BracketType[BracketPosition] == "{" then
              Brackets[BracketID] = nil
              BracketLine[BracketPosition] = nil
              BracketLinePosition[BracketPosition] = nil
              BracketEnd[BracketPosition] = Script.Position
            else
              return Script:Error("unexpected symbol '}'")
            end
          else
            return Script:Error("unexpected symbol '}'")
          end
          Script:NextCharacter()
        elseif Char == ")" then
          local BracketID = #Brackets
          if BracketID > 0 then
            local BracketPosition = Brackets[BracketID]
            if BracketType[BracketPosition] == "(" then
              Brackets[BracketID] = nil
              BracketLine[BracketPosition] = nil
              BracketLinePosition[BracketPosition] = nil
              BracketEnd[BracketPosition] = Script.Position
            else
              return Script:Error("unexpected symbol ')'")
            end
          else
            return Script:Error("unexpected symbol ')'")
          end
          Script:NextCharacter()
        elseif Char == "]" then
          local BracketID = #Brackets
          if BracketID > 0 then
            local BracketPosition = Brackets[BracketID]
            if BracketType[BracketPosition] == "[" then
              Brackets[BracketID] = nil
              BracketLine[BracketPosition] = nil
              BracketLinePosition[BracketPosition] = nil
              BracketEnd[BracketPosition] = Script.Position
            else
              return Script:Error("unexpected symbol ']'")
            end
          else
            return Script:Error("unexpected symbol ']'")
          end
          Script:NextCharacter()
        elseif Char == "\"" then
          local String = ""
          while true do
            Script:NextCharacter()
            Char = Script:ReadCharacter()
            if not Char then
              Script:Error("unfinished string")
            elseif Char == "\\" then
              Script:NextCharacter()
              Char = Script:ReadCharacter()
              if Char == "n" then
                String = String .. "\n"
              else
                String = String .. Char
              end
            elseif Char == "\"" then
              Script:NextCharacter()
              break
            else
              String = String .. Char
            end
          end
       
          -- Push string to the values table
          table.insert(ValueTable, {Value = String})
        elseif Char:find("[0-9]") then
          local Number = Char
          while true do
            Script:NextCharacter()
            Char = Script:ReadCharacter()
            if not Char then
              break
            elseif Char:find("[0-9]") then
              Number = Number .. Char
            end
          end
          Number = tonumber(Number)
         
          -- Push number to the values table
          table.insert(ValueTable, {Value = Number})
        elseif Char == " " then
          -- Skip space character
          Script:NextCharacter()
         
          if Key:len() > 0 then
            table.insert(ValueTable, {Name = Key})
            Key = ""
          end
        elseif Char:find("[a-zA-Z]") then
          -- Keyword / variable / function
          Script:NextCharacter()
          Key = Key .. Char
        elseif self.Operators[Char] then
          if Key:len() > 0 then
            table.insert(ValueTable, {Name = Key})
            Key = ""
          end
         
          -- Found operator
          if #ValueTable > 0 and #OperatorTable == 0 then
            table.insert(OperatorTable, self.Operators[Char][1])
          elseif #OperatorTable > 0 then
            return Script:Error("unexpected symbol '"..Char.."'")
          elseif #ValueTable == 0 then
            return Script:Error("expecting value before symbol '"..Char.."'")
          end
          Script:NextCharacter()
        else
          return Script:Error("unexpected symbol '"..Char.."'")
        end
      end
    end

    function StateBase:DoString(String)
      local Script = self:LoadString(String)
      if Script then
        return Script
      end
    end

    function StateBase:LoadFile(Source)
      local File = io.open(Source, "r")
      if File then
        local String = File:read("*a"); File:close()
        local Script = self:LoadString(String, Source)
        return Script
      end
    end

    function StateBase:DoFile(Source)
      local Script = self:LoadFile(Source)
      if Script then
        return Script()
      end
    end

    function StateBase:New()
      local State = {Env = {}}
      setmetatable(State, StateMetatable)
     
      return State
    end

    S = StateBase:New()
    S:DoFile("input.txt")

      Current date/time is Sun Jan 21, 2018 1:40 am