hpaste

recent | annotate | new

Dylan:

define function parse-telemetry (string :: <string>) => (world :: <world>)
  let strings = split(string, ' ');
  let index :: <integer> = 1;
  let stat = make(<stretchy-vector>);
  let mov = make(<stretchy-vector>);
  //let mov = make(limited(<stretchy-vector>, of: <world-object>));
  local method parsef () => (float :: <fp>)
          let f = string-to-float(strings[index]);
          index := index + 1;
          as(<fp>, f);
        end;
  local method parseobj () => ()
          let f = strings[index][0];
          index := index + 1;
          if (f == 'b')
            add!(stat, make(<boulder>,
                            x: parsef(),
                            y: parsef(),
                            radius: parsef()));
          elseif (f == 'c')
            add!(stat, make(<crater>,
                            x: parsef(),
                            y: parsef(),
                            radius: parsef()));
          elseif (f == 'h') // and drop
            make(<home-base>,
                 x: parsef(),
                 y: parsef(),
                 radius: parsef());
          elseif (f == 'm')
            add!(mov, make(<martian>,
                           x: parsef(),
                           y: parsef(),
                           direction: parsef().degree-to-radian,
                           speed: parsef()));
          end;
        end;
  local method parsectl () => (acc :: <symbol>, turn :: <symbol>)
          let acc = strings[index][0];
          let tur = strings[index][1];
          let a = if (acc == 'a')
                    #"accelerating"
                  elseif (acc = 'b')
                    #"braking"
                  elseif (acc = '-')
                    #"rolling"
                  end;
          let t = if (tur == 'L')
                    #"hard-left"
                  elseif (tur == 'l')
                    #"left"
                  elseif (tur == '-')
                    #"straight"
                  elseif (tur == 'r')
                    #"right"
                  elseif (tur == 'R')
                    #"hard-right"
                  end;
          index := index + 1;
          values(a, t);
        end;
  let ts = parsef() / 1000.0s0;
  let (acc, tur) = parsectl();
  let rov = make(<rover>,
                 acceleration-state: acc,
                 turning-state: tur,
                 x: parsef(),
                 y: parsef(),
                 direction: parsef().degree-to-radian,
                 speed: parsef());
  while (index < strings.size - 1)
    parseobj();
  end;

------------------------------------------------------------------------------
-- Haskell:

telemetry :: Parser Message
telemetry = do ts <- int
               state <- accelStateParser
               turning <- turningStateParser
               spaces
               x <- double
               y <- double
               dir <- double
               speed <- double
               obstacles <- obstaclesParser
               messageEnd
               return $ Telemetry ts state turning x y dir speed obstacles

accelStateParser :: Parser AccelState
accelStateParser = (accelerating <|> braking <|> rolling)

accelerating = stateParser 'a' Accelerating
braking = stateParser 'b' Braking
rolling = stateParser '-' Rolling

stateParser :: Char -> a -> Parser a
stateParser c cons = do _ <- char c
                        return cons

turningStateParser :: Parser TurningState
turningStateParser = hardleft <|> softleft
                         <|> hardright <|> softright
                         <|> straight

hardleft  = stateParser 'L' HardLeft
softleft  = stateParser 'l' SoftLeft
hardright = stateParser 'R' HardRight
softright = stateParser 'r' SoftRight
straight  = stateParser '-' Straight
obstaclesParser :: Parser [Object]
obstaclesParser = do l <- many obstacleParser
                     return l

obstacleParser :: Parser Object
obstacleParser = do code <- oneOf "bchm"
                    spaces
                    case code of
                         'b' -> object Boulder
                         'c' -> object Crater
                         'h' -> object Home
                         'm' -> martian
                         _   -> error "Can't get here in parser!"

object :: (Circle -> a) -> Parser a
object cons = do x <- double
                 y <- double
                 r <- double
                 spaces
                 return $ cons (Circle (x:.y) r)

martian :: Parser Object
martian = do x <- double
             y <- double
             dir <- double
             speed <- double
             spaces
             return $ Martian (Circle (x:.y) 0.4) dir speed